测试时无法使用 MemoryRouter 导航到路径

Oli*_*ins 7 jestjs react-router enzyme

我已经密切关注这些示例,但我无法让MemoryRouter(您应该如何测试路由组件?)来使用 jest 和酶进行测试。

我想导航到其中一条路线,并将其反映在我的快照中。下面的代码尝试使用 MemoryRouter 导航到“/A”,所以我想我会看到<div>A</div>

import React from 'react';
import Enzyme, {mount} from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import {BrowserRouter as Router, MemoryRouter, Route, Switch} from 'react-router-dom';

Enzyme.configure({adapter: new Adapter()});

describe('Routing test', () => {
    let wrapper;

    beforeEach(() => {
        wrapper = mount(
            <MemoryRouter initialEntries={["/A"]}>
                    <div className={"Test"}>This is my Test Component and should not have any test specific code in it
                        <Router>
                            <Switch>
                                <Route path={"/A"}>
                                    <div className={"A"}>A</div>
                                </Route>
                                <Route path={"/B"}>
                                    <div>B</div>
                                </Route>
                            </Switch>
                        </Router>
                    </div>
                </MemoryRouter>
        );
    });
    afterEach(() => {
        wrapper.unmount();
    });

    it('matches snapshot', () => {
        expect(wrapper.find(".Test")).toHaveLength(1); //this ok
        expect(wrapper.find(".A")).toHaveLength(1); //but this is not ok :( It should find  A
    });
});
Run Code Online (Sandbox Code Playgroud)

而不是看到<div>Test<div>A</div></div>我只是看到<div>Test</div>

注意:我的示例被简化为一类。我的真实世界情况是这<div>Test...</div>是一个单独的组件。

Oli*_*ins 4

好吧,我想通了。

它非常丑陋,但您需要创建一个__mocks__目录(在项目的第一级)。__mocks__似乎文档很少,但这似乎是一个笑话,这里的所有内容都将在测试时运行,在这里您可以为某些外部库添加模拟存根。

import React from 'react';

const reactRouterDom = require("react-router-dom")
reactRouterDom.BrowserRouter = ({children}) => <div>{children}</div>

module.exports = reactRouterDom
Run Code Online (Sandbox Code Playgroud)

我的测试文件与我的问题相同(我认为):

import React from 'react';
import Enzyme, {mount} from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import {BrowserRouter as Router, MemoryRouter, Route, Switch} from 'react-router-dom';

Enzyme.configure({adapter: new Adapter()});

describe('Routing test', () => {
    let wrapper;

    beforeEach(() => {
        wrapper = mount(
            <MemoryRouter initialEntries={['/A']}>
                    <div className={"Test"}>This is my Test Component and should not have any test specific code in it
                        <Router>
                            <Switch>
                                <Route path={"/A"}>
                                    <div className={"A"}>A</div>
                                </Route>
                                <Route path={"/B"}>
                                    <div>B</div>
                                </Route>
                            </Switch>
                        </Router>
                    </div>
                </MemoryRouter>
        );
    });
    afterEach(() => {
        wrapper.unmount();
    });

    it('matches snapshot', () => {
        expect(wrapper.find(".Test")).toHaveLength(1); //this ok
        expect(wrapper.find(".A")).toHaveLength(1); //but this is not ok :( It should find  A
    });
});
Run Code Online (Sandbox Code Playgroud)

这有效,我的测试是绿色的!:)

更新 :

我想我有点困惑,因为我像对待任何其他 React 组件一样对待 Router,而它实际上是像 redux 这样的顶级组件Provider。路由器不应位于内部App,而应位于外部App(例如在index.js文件中)。

ReactDOM.render(
    <Provider store={store}>
        <Router>
            <App/>,
        </Router>
    </Provider>,
    document.getElementById('root')
);
Run Code Online (Sandbox Code Playgroud)

现在,在针对 App 编写测试时,我提供了自己的路由器,例如MemoryRouter