我有以下父屏幕/组件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 />
是一个子组件,它是使用reduxForm
到connect
的装饰形式,以标准方式导入父级。
PasswordForm.tsx
const PasswordForm = reduxForm({
form: 'password-form'
})(PasswordFormStatic)
在我的测试中,我对这个子组件<PasswordForm>
的功能不感兴趣,所以我想模拟该组件,并确保模拟组件仍然存在于父组件的快照测试中(Employees.tsx
)。
jest.mock()
我以为会处理这件事。这是Employees.spec.tsx
describe('Employees Scene', () => {
let wrapper
const requestAuthToken = jest.fn()
jest.mock('../../components/Forms/PasswordForm', () => {
const mockedPasswordForm = () => null
return mockedPasswordForm
})
但是,我仍然会收到Invariant Violation: Could not find "store" in either the context or props...
的错误,这实际上是对孩子的抱怨。
所以看来jest.mock()
这里没有嘲笑我的组件?因为它仍然试图渲染和抱怨缺乏商店。
如何使用React-Native在Jest中正确模拟组件(特别是子项)?
答案 0 :(得分:2)
你的问题与react或reduc无关,而是与javascript import mecanism相关:
因为PasswordForm是在Employees.tsx文件的顶部导入的,然后(可能)导入了在测试用例顶部的Employees,这使得加载按以下顺序进行:PasswordForm&gt;员工&gt; Employees.spec(因为导入发生在任何其他语句之前)
您在测试用例中创建的模拟在Employees类中是未知的。
Jest提供了一种处理这种情况的方法,我会用一些简单的代码来完成这个问题
首先,让我们重现问题
一个简单的函数返回1
./src/A.js
const fn = () => 1
export default fn
一个简单的函数,使用之前定义的A
./src/B.js
import A from 'A'
const B = () => A() + 1
export default B
最后测试B函数,尝试模拟A,就像你的情况一样
./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)
})
这导致
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
现在,如果您使用jest模拟模块,如此处所述https://facebook.github.io/jest/docs/en/manual-mocks.html
创建新文件
A的模拟(&#39; _ _ mocks _ _&#39;文件夹名称很重要)
./__mocks__/A.mock.js
const A = jest.fn(() => 0)
export default A
并将测试文件修改为
import A from 'A'
import B from 'B'
jest.mock('A')
test('use jest mock for A', () => {
expect(B(1)).toBe(1)
})
你最终会得到你想要的东西
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