gpt4 book ai didi

reactjs - react /Mobx : Integration Tests with Stores Injected into Child Components

转载 作者:行者123 更新时间:2023-12-03 13:43:45 25 4
gpt4 key购买 nike

我们正在尝试为所有现有的 React 组件编写单元/集成测试。目前,我们正在将 React 与 Mobx 4 结合使用,测试主要使用 React-testing-library/jest 编写。我们确实在某些区域使用了 Enzyme 来利用浅层渲染。我们的问题是,当我们访问某些“页面”或容器组件时,我们会收到诸如“MobX 注入(inject)器:存储‘teamStore’不可用!请确保它由某些提供商提供”之类的错误

我们做了一些挖掘,但在搜索类似问题时找不到任何可供引用的内容。我们确实知道这是由子组件引起的,这些子组件直接将存储注入(inject)其中,并被调用到我们的容器/页面中。

我的问题是:测试框架内是否有任何方法可以将容器组件中创建的模拟存储传递给子组件?显然,如果我们将 store 作为 prop 从父级传递给子级,就可以解决问题,但我们试图避免以任何方式修改组件本身。

如果上述不可能,我们是否有其他选择,无需重构组件来根据需要传递存储,而不是直接注入(inject)到子组件中?


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 的一部分来提供您自己的模拟存储,因此您可以提供自己的注入(inject)函数,而不是运行真正的注入(inject)函数。

使用该自定义注入(inject)函数,您可以返回一个假商店(需要与原始商店匹配相同的接口(interface))。

如果您想通过导入您创建的模拟来预先填充存储值(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 注入(inject)函数,您就可以通过以下方式引用存储来预填充值:

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>
)
});

关于reactjs - react /Mobx : Integration Tests with Stores Injected into Child Components,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55363381/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com