我们正在尝试为所有现有的 React 组件编写单元/集成测试。我们目前正在使用 Mobx 4 的 React,测试主要使用 react-testing-library/jest 编写。我们确实在某些区域使用了酶来利用浅层渲染。 我们的问题是,当我们到达某些"页面"或容器组件时,我们收到诸如"MobX 注入器:商店'teamStore'不可用!确保它是由某个提供商提供的">
我们已经做了一些挖掘,但在搜索类似问题时找不到任何参考内容。我们确实知道这是由子组件引起的,这些子组件直接将存储注入其中,并被调用到我们的容器/页面中。
我的问题是:在测试框架中是否有任何方法可以将在我们的容器组件中创建的模拟存储传递给子组件?显然,如果我们将商店作为道具从父级传递给子级,则可以解决问题,但是我们试图避免以任何方式修改组件本身。
如果上述方法无法实现,我们是否有任何其他选择,而无需重构组件以根据需要传递存储,而不是直接注入到子组件中?
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { Container, Grid, Segment } from "semantic-ui-react";
import ChildComp from "../../components/ChildComp";
@inject("userStore")
@observer
class ParentComponent extends Component {
render() {
return (
<Container className="parent">
<Segment basic>
<h1>Hello</h1>
<ChildComp />
</Segment>
</Container>
);
}
}
export default ParentComponent;
import React, { Component } from "react";
import { inject, observer } from "mobx-react";
import { Container, Grid, Segment } from "semantic-ui-react";
@inject("teamStore")
@observer
class ChildComp extends Component {
render() {
return (
<Segment basic>
<p>How can I help you?</p>
</Segment>
);
}
}
export default ChildComp;
使用jest,你可以模拟mobx的部分来提供你自己的模拟存储,这样你就可以提供自己的注入函数,而不是运行真正的注入函数。
使用该自定义注入函数,您可以返回一个假商店(需要与原始商店匹配相同的接口)。
如果要通过导入创建的模拟来用值预填充存储(jest 不允许在使用 jest.mock 时使用模块/全局作用域上的变量)
这是实现此目的的示例代码(这是在stackoverflow上编写的未经测试的代码,因此可能需要一些调整才能正确)。
jest.mock('mobx-react', () => {
// get the original reference to mobx-react
const originalMobx = require.requireActual('mobx-react');
// create your fake stores, they should have the same interface as the real store
const mockStores = {
userStore: new UserStore()
};
return {
...originalMobx, // allow to import the original properties in react-mobx
// override the inject decorator to instead return the fake store as a prop
inject: (injectName) => (component) => (props) => {
// render the real component with the additional prop
return react.createElement(component, {...props, [injectName]: mockStores[injectName] })
},
mockStores // Allows access afterwards via import e.g import { mockStores } from 'mobx-react'
}
});
模拟 mobx-react 注入函数后,您可以引用存储以通过以下方式预填充值:
import { mockStores } from 'mobx-react';
test('my test', () => {
mockStores.userStore.clearUsers();
// render the component here
})
还有一种替代解决方案,您可以用mobx-react
的Provider
包裹测试的组件并提供假货。
因此,测试将事先初始化它们并传递上下文。
例如
test('my comp', () => {
const userStore = new UserStore();
const component = shallow(
<Provider userStore={userStore}>
<MyComponent />
</Provider>
)
});