Getting console errors when using jest.mock for React components - reactjs

When I mock a react component like this jest.mock('react-slick', () => 'div'); I get console errors for unknown props passed to tag. I know these errors don't mean anything in this case, but it's quite annoying to see them in the output:
Is there a way to disable these errors? Maybe just don't pass any props to the component when it is mocked?

You can just mock the console.error, like so:
console.error = jest.genMockFn()
Jest will still fail the tests regardless of the above.

Related

Using jest and useFormik, getting an error on destructuring

I have a component that is following the useFormik pattern like this.
const formikOptions:FormikConfig<FormType> = someFormikOptions
const formik = useFormik(formikOptions)
const {values, handleSubmit, dirty, } = formik
Then I toss in a <FormikProvider value={formik}> in the component, and everything works fine on the front end when I run everything. No errors reported at build time, no console warnings, no issues. Woohoo!
Then I come to my spec file where we use jest and enzyme. We recently added an option that resets all mocks between tests (not my decision, not a decision that I can overrule, please do not tell me to yell at my CTO to fix this). One of my now-failing tests looks like this:
decribe('the component name',()=>{
it('should render',()=>{
const wrapper = shallow(<TheComponent {...ownProps} />)
expect(wrapper).toMatchSnapshot()
}
}
When I run this code, I'm getting an error:
TypeError: Cannot destructure property 'values' of 'formik' as it is undefined.
I've tried spying on useFormik and mocking a return value with a clearly defined values return object, but I've been unsuccesful. I'm not sure what I'm doing wrong here. Whenever I google, I'm getting information strictly for useFormikContext, never for useFormik. Why am I seeing this type error, and how can I mend it?

Error using userEvent with React Testing Library and react-select AsyncSelect (but only in CodeSandbox?)

I created this CodeSandbox so I could demonstrate a problem with related code (the onChange not firing in a test):
https://codesandbox.io/s/festive-tree-xkw8s?file=/src/App.test.js
However in CodeSandbox I can't even get that far because as soon as I call
userEvent.type(securityField, 'abc{enter}')
I get a set this error in the console:
Error: Uncaught [TypeError: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.]
and as a result the loadOptions callback of AsynSelect is never triggered (locally I'm not having any issue with that, just the onChange which isn't firing).
I have not been able to find any examples of or guidance on this error. I haven't used CodeSandbox a lot so maybe I'm missing something basic.
I am not seeing this error in my local environment but I am trying to solve it because I want to finish setting up my original problem.
You want to use react-select-event for interacting with your react-select in testing. This was made specifically for testing with react-testing-library.

Errors when using React Testing Library and renderHook to test hooks with multiple contexts

Solved
Issue is tracked on github
I was attempting to test custom hooks using the react testing library, and the hook I was trying to put under test requires multiple context providers to work correctly. (authentication and notification)
The documentation here only outlines creating a wrapper with a single provider like so:
const wrapper = ({ children }) => <ContextProvider>{children}</ContextProvider>
However, my implementation needed something more complex, like so:
const wrapper = ({ children }) => (
<ToastProvider>
<NotificationProvider>
<AuthProvider>{children}</AuthProvider>
</NotificationProvider>
</ToastProvider>
);
This was was failing at every attempt with the errors:
TypeError: parentInstance.children.indexOf is not a function
OR
Invariant Violation: Drop(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.
Leading me to believe there was no clear way to provide the right context without abandoning renderHook all together and building a test component that could fire off the necessary behaviors manually.
After a lot more digging I found this error buried in the logs:
Warning: An invalid container has been provided. This may indicate that another renderer is being used in addition to the test renderer. (For example, ReactDOM.createPortal inside of a ReactTestRenderer tree.) This is not supported.
Surely enough, it turns out there is a conflict with react-test-renderer and react-dom which causes calls to ReactDOM.createPortal to fail when under test. I assume this is somewhere in the ToastProvider, but the workaround is pretty simple.
Solved by adding this to the top of my test:
ReactDOM.createPortal = node => node

Exception handling in Jest/Enzyme

I am testing my React components using Jest/Enzyme.
In some of the test cases, the test fails with some exception.
What is a sane/standard way to handle error in Jest/Enzyme instead of breaking the test case?
e.g - the following case should pass if the 'Grid' component does not get any data as parameter.However, it fails with an exception which is being thrown out of the Grid component.
test('Grid does not render without data',()=>{
const wrapper=shallow(<Grid/>);
expect(wrapper.length.toBe(0));
})
You should not handle error in your test cases. Instead you should expect the code to throw errors.
You code should look something like this
test('Grid should throw when data is not passed',()=>{
expect(() => shallow(<Grid/>)).toThrow();
})
But ideally, when the right prop is not there, the component should not throw, instead, it should not render.

Understand error with Jest, Enzyme and React using contains

The pattern to check if a React component contains something with Enzyme + Jest seems to be this one:
expect(shallow(<Field title="hello" />).contains(<p id="hello"></p>)).toBe(true);
The main problem I face with this kind of code is that I have no clue what the problem is if the expectation fails. Because it uses the pattern "expect boolean to be boolean", the only error I get is:
expect(received).toBe(expected) // Object.is equality
Expected: true
Received: false
It does not really help. Is there a way to get more precise error when testing if a React element contains something?
Yes, there are more ways of checking if the element is present within the component. And if your test case fails you can debug the wrapper to check what went wrong. .debug() won't pinpoint the error but I think it will make debugging very easy since you get what is being rendered by shallow/mount.
The following command will help you debug a wrapper.
const wrapper = shallow(<Field title="hello" />);
console.log(wrapper.debug());
I have created a sandbox to demonstrate the same there I use 'contains' and 'find' on the wrapper to check if p is present with id as "hello" and also on the console you can see the output of wrapper.debug()
https://codesandbox.io/s/886799791j

Resources