I am using enzyme with jest and trying to print out wrapper.debug but I am not getting output as shown in jest docs. what is wrong here?
my test file:
import React from 'react';
import Enzyme, {shallow} from 'enzyme';
import EnzymeAdapter from 'enzyme-adapter-react-16';
import App from './../../components/App/App';
Enzyme.configure({ adapter : new EnzymeAdapter() });
it('should render without crashing', () => {
const wrapper = shallow(<App />)
console.log(wrapper.debug());
});
my console output is this :
PASS src/test/integration/App.test.js
● Console
console.log src/test/integration/App.test.js:14
<ContextConsumer>
[function bound renderWrappedComponent]
</ContextConsumer>
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.8s
Ran all test suites related to changed files.
The shallow rendering is useful to test a component as a unit so it won't dive and look for your component within <ContextConsumer>.
Some options:
You could shallow directly the component within <ContextConsumer>.
You could change shallow with mount which render the full DOM rendering (probably not your intent here).
Use .dive() which shallow render the one non-DOM child of the current wrapper. Doc
Related
I'm attempting to write some tests for my react native app. A component in my app focuses a TextInput after a parent Pressable receives a press. I'm using a ref to identify and focus the TextInput element.
My desired functionality works just fine when running my app through expo, but my test is failing because it seems that the onFocus event is not being called.
Why isn't ref.current.focus() being called when running tests via the #testing-library/react-native library?
Here's my code:
Foo.js
import {Pressable, TextInput} from "react-native";
import {useRef} from "react";
const Foo = (props) => {
const inputRef = useRef()
return (
<Pressable testID={"pressable"} onPress={() => inputRef.current.focus()}>
<TextInput ref={inputRef} testID={"input"} onFocus={props.onFocus} />
</Pressable>
)
}
export default Foo;
Foo.test.js
import { render, screen, fireEvent } from '#testing-library/react-native';
import Foo from "./foo";
test('onFocus is called after press', () => {
const mockFocus = jest.fn();
render(<Foo onFocus={mockFocus} />)
// fireEvent(screen.getByTestId("input"), 'focus');
fireEvent.press(screen.getByTestId("pressable"));
expect(mockFocus).toHaveBeenCalled()
});
This test fails with the following message:
Error: expect(jest.fn()).toHaveBeenCalled()
Expected number of calls: >= 1
Received number of calls: 0
I created an issue on the RNTL GitHub page and received a response from a contributor. Copying and pasting here for easy reference for anyone who might stumble upon this thread.
This is expected as React Test Renderer which we use for rendering
does not support refs. Check #1006 for more details.
Since the behaviour of focus() triggering onFocus event would probably
involve roundtrip to native side (from JS side), then you actually
cannot test such behaviour using RNTL as we do not run native code (see
here for details).
That leaves you with following options:
Call fireEvent.focus to manually trigger onFocus on relevant
TextInput. Recommended in case focus assertion would be a part of a
step in a bigger test.
Use createNodeMock to pass ref creating function to render method, More details here. Recommended in case you
just want to assert pressing button triggers onFocus.
Is there a way to test how the page render in next.js?
Not by comparing the html, but the actual images.
So far I only found a way to "render" the component into a html (tags tree) with toJSON():
import React from 'react'
import TestRenderer from 'react-test-renderer'
import Index from './index'
it(`should render`, () => {
const testRenderer = TestRenderer.create(<Index/>)
expect(testRenderer.toJSON()).toMatchSnapshot()
})
But there is no information on how to do this with the actual rendering and real images.
At the very end I want to be able to compare the current image to the reference with pixel-perfect accuracy.
Is it possible?
You want to look for tools to do visual testing. Generally the setup is such that you run the test once, it creates screenshots, and then when you run it later again it compares against those screenshots to see if any regression occurred.
This person explains a setup with a nextJs app, cypress and applitools
I am currently trying to write some unit tests for my web application that I made with Nuxt, Vue and Vuetify. I decided to use the Jest framework and the vue-test-utils to write unit tests, but it seems like Jest or vue-test-utils refuses to mount my components.
Example
Let’s take this very simple test where i shallowMount my component and see if the component renders a div:
require("jsdom-global")();
import AlbumHeader from "#/components/Album/AlbumHeader";
import { shallowMount } from "#vue/test-utils";
describe("AlbumHeader.vue", () => {
it("renders a div", () => {
const wrapper = shallowMount(AlbumHeader);
expect(wrapper.contains("div")).toBe(true);
});
});
When I run this unit test it always fails with the error:
TypeError: Cannot read property 'child' of undefined
I feel like the problem has something to do with Vuetify. But even after creating new Vuetify instances in my test and creating a localVue I still cannot get it to pass the test. I feel like I have read every article on this topic and none of them seem to help. This is also the first time I use this framework so I really do not have a clue where this problem takes place.
I hope someone can explain to me what i am doing wrong and how i can fix it, i would really appreciate that.
I have followed –or tried to– several posts on how to do it, including the airbnb enzyme's guide for (separatedly) react-native and jest. (E.g: https://medium.com/#childsmaidment/testing-react-native-components-with-enzyme-d46bf735540#.6sxq10kgt, https://blog.callstack.io/unit-testing-react-native-with-the-new-jest-i-snapshots-come-into-play-68ba19b1b9fe#.4iqylmqh5 or How to use Jest with React Native)
But I keep getting lots of warnings (I have multiple set of concurrent tests) whenever I try to render (not mount, it crashes) any native component. Warnings are always about a native prop not being recognised.
Warning: Unknown props `focus`, `secureTextEntry` on <TextInput> tag. Remove these props from the element.
in TextInput (created by TextInput)
in TextInput (created by PasswordInput)
Anyone who has a set up working, recognises how to remove the warning or how to solve it?
Thanks
So I know this is a bit old but I was having issues with Jest, Enzyme, and React Native and I found this post - hopefully this solution will help.
To start with - Enzyme doesn't support mounting React Native and only supports shallow rendering. This wasn't good enough for me as I needed end-to-end tests from the component to the api which lead me to react-native-mock-render. What this does is allow us to run react native inside a browser environment which let's us test using Enzyme - all the calls for React Native and the components work as you would expect.
To set this up you'll need to install JSDOM, react-native-mock-render, Enzyme 3.0+, and Jest 20.0.0+. And then inside your jest setup file (which is specified in your package.json) include the following code:
const { JSDOM } = require('jsdom');
const jsdom = new JSDOM();
const { window } = jsdom;
function copyProps(src, target) {
const props = Object.getOwnPropertyNames(src)
.filter(prop => typeof target[prop] === 'undefined')
.map(prop => Object.getOwnPropertyDescriptor(src, prop));
Object.defineProperties(target, props);
}
global.window = window;
global.document = window.document;
global.navigator = {
userAgent: 'node.js',
};
copyProps(window, global);
// Setup adapter to work with enzyme 3.2.0
const Enzyme = require('enzyme');
const Adapter = require('enzyme-adapter-react-16');
Enzyme.configure({ adapter: new Adapter() });
// Ignore React Web errors when using React Native
console.error = (message) => {
return message;
};
require('react-native-mock-render/mock');
And that's it - you're all setup to mount components in Enzyme and test them.
If you want to see a full sample check out react-native-mock-render-example. This is working with React 16, React Native 0.51, and Enzyme 3.2.
In order to unit test your component with jest you can use enzyme-to-json
npm install --save enzyme-to-json
then your test would look like this:
import { shallow } from 'enzyme';
import { shallowToJson } from 'enzyme-to-json';
import MyComponent from './MyComponent';
it('should render component', => {
expect(shallowToJson(shallow(<MyComponent />))).toMatchSnapshot();
});
I'm not sure regarding your case with react-native.
I can share my case of using jest + enzyme with standard react.
When I needed to test some component and isolate it from others I used jest.mock, e.g.
jest.mock('../ComponentToBeMocked', () => {
return () => null;
});
Initially I found examples when the second argument (a function) should return just a string representing a name of the mocked component. But in that case I saw that distracting Unknown props warning.
I am using a HOC in a React component that looks like:
import React from 'react';
import Wrapper from 'wrapper';
class Component extends React.Component {
render () {
return (
<div className='component' />
)
};
}
export default Wrapper(Component)
When testing Component using Mocha I am attempting to look for a class name that should be contained within Component. Like so:
describe('Component', function () {
it('can be mounted with the required class', function () {
const component = shallow(
<Component />
);
expect(component).to.have.className('component');
});
});
The problem is that Mocha doesn't know to look within the wrapper for the Component and attempts to find it in the HOC. Which of course it will not.
The error I am receiving is:
AssertionError: expected <Wrapper(Component) /> to have a 'component' class, but it has undefined
HTML:
<div class="component">
</div>
How do I tell Mocha to look within the HOC for the correct location of the class name instead of the HOC itself?
You can use enzyme .dive()
const component = shallow(<Component />).dive();
expect(component.props().className).toEqual('component')
The problem is the use of Enzyme's shallow instead of mount, which is required when testing HOC's.
So, use mount.
I added this to a github project so you can see. Use my redux-form-test project and be sure to use the stackoverflow-question-38106763 branch. See the tests/unit/index.js file.
Be sure to read the source code of the test file. One of tests fails intentionally to reproduce your issue.
What's tricky in this situation is that the render method of the HOC exactly replicates the component it's wrapping. See the render method in the source of the react-onclickoutside component you mention. That's why the AssertionError you see is confusing: it shows you HTML that looks like it's satisfying the assertion. However, if you run
console.log(component.debug())
before your expect, it'll show
<Component />
That's because shallow only goes one level deep. And enzyme is not using the rendered HTML for the assertion, it's using the React elements, which does not have the component class on it, as you can see.