I have the following parent screen/component Employees.tsx
import PasswordForm from '../../components/Forms/PasswordForm'
...
<View style={ stylesheet.modalWrapper }>
<PasswordForm
errorMessage={ auth.error }
isWorking={ auth.isWorking }
onCancel={ toggleModal }
onSubmit={ customSubmitHandler }
/>
</View>
<PasswordForm /> is a child component that is a decorated form using reduxForm to connect, imported into the parent in the standard way.
PasswordForm.tsx
const PasswordForm = reduxForm({
form: 'password-form'
})(PasswordFormStatic)
In my tests, I am not interested in the functionality of this child component <PasswordForm> so I want to mock that component, and just make sure that the mocked component is still present in the snapshot test of the parent component (Employees.tsx).
jest.mock() I thought would handle this. This is Employees.spec.tsx
describe('Employees Scene', () => {
let wrapper
const requestAuthToken = jest.fn()
jest.mock('../../components/Forms/PasswordForm', () => {
const mockedPasswordForm = () => null
return mockedPasswordForm
})
However, I still get the error that Invariant Violation: Could not find "store" in either the context or props... which is really a complaint about the child.
So it appears jest.mock() here is not mocking my component? As it is still trying to render and complain about the lack of a store.
How do I properly mock components (specifically children) in Jest with React-Native?
Your problem is not related to react or reduc, but to the javascript import mecanism :
Because PasswordForm is imported on the top of Employees.tsx file, and then Employees is (likely) imported at the top of your test case, this makes the load happen in this order : PasswordForm > Employees > Employees.spec (because imports happen before any other statements)
The mock you create in the test case is unknown by the Employees class.
Jest provides a way to handle this scenario, Ill do it with some simple code that illustrate perfectly the problem
First, lets reproduce the issue
a simple function returning 1
./src/A.js
const fn = () => 1
export default fn
a simple function, using the A defined before
./src/B.js
import A from 'A'
const B = () => A() + 1
export default B
finally a test for B function that tries to mock A as you do in your case
./test/B.test.js
import B from 'B'
test('Try to mock A on the fly', () => {
jest.mock('../src/A', () => 0)
expect(B(1)).toBe(1)
})
this results in
FAIL test\B.test.js
× Try to mock A on the fly (10ms)
● Try to mock A on the fly
expect(received).toBe(expected) // Object.is equality
Expected value to be:
1
Received:
2
2 | test('Try to mock A on the fly', () => {
3 | jest.mock('../src/A', () => 0)
> 4 | expect(B(1)).toBe(1)
5 | })
at Object.<anonymous> (test/B.test.js:4:18)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 2.598s
Now if you use jest mock module as explained here https://facebook.github.io/jest/docs/en/manual-mocks.html
By creating a new file
a mock for A (the '_ _ mocks _ _' folder name is important)
./__mocks__/A.mock.js
const A = jest.fn(() => 0)
export default A
and modifying your test file to
import A from 'A'
import B from 'B'
jest.mock('A')
test('use jest mock for A', () => {
expect(B(1)).toBe(1)
})
you will end up with what you want
PASS test\B.test.js
√ use jest mock for A (4ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.57s
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With