Mobx反应测试组件

问题描述

这让我发疯。测试如何通过useContext与mobx反应? 我正在尝试开玩笑和酵素,但是当我尝试

isnoresults(documents,p){
  let pipe = new PlanCodePipe();
  let transform = pipe.transform(documents,p.planCode);
  return transform?.length == 0;
}

export const HelloWorldView = observer(() => {
    const { store } = useHelloWorldController()
    const dataStore = store.datastore

    return (
        <>
            <displayVersion version={dataStore.versionNumber} />
        </>
    )
})

商店是简单的mobx商店

export const useHelloWorldController = () => React.useContext(React.createContext({
  store: store,}));

我尝试过

export class Store {
    @observable
    versionNumber?: string

    @action
    changeVersion(versionNumber: string){
        this.versionNumber = versionNumber
    }
}

但是我得到了

const store = observable({ versionNumber: "1.2.0",changeVersion: jest.fn() }) jest.mock("../HelloWorldPage",() => ({ ...jest.requireActual("../HelloWorldPage"),useHelloWorldController: () => ({ store: { datastore: store } }) })); describe("HelloWorldView",() => { test("display version number",async () => { const wrapper = render(<HelloWorldView />); expect(await wrapper.queryByText("1.9.2")?.textContent).toEqual("1.9.2") // VERSION }) 的模块工厂不允许引用任何 范围外的变量。

已经尝试过使用doMock,但这根本不起作用

解决方法

我更改了设置提供商的方式

export const helloWorldContext = React.createContext({ store: controller })
export const useHelloWorldController = () => React.useContext(helloWorldContext);

现在我可以测试:

import React from "react";
import { render,fireEvent,screen } from '@testing-library/react'
import { HelloWorldView } from "./HelloWorldView";
import { helloWorldContext } from "../HelloWorldPage";
import { HelloWorldController } from "../../controllers/HelloWorldController";
import { HelloWorldDI } from "../../config/HelloWorldDI";
import { HelloWorldDS } from "../../datastores/HelloWorldDS";
import { mocked } from 'ts-jest/utils';

jest.mock('../../datastores/HelloWorldDS',() => {
    return {
        HelloWorldDS: jest.fn().mockImplementation(() => {
            return {
                versionNumber: "1.2.0",changeVersion: jest.fn()
            };
        })
    };
});

describe("HelloWorldView",() => {
    // mock
    const HelloWorldDSMock = mocked(HelloWorldDS,true);
    beforeEach(() => {
        HelloWorldDSMock.mockClear();
    });

    test("display version number",async () => {
        // UT
        const controller = new HelloWorldController(new HelloWorldDI(),new HelloWorldDS());
        const wrapper = render(
            <helloWorldContext.Provider value={{ store: controller }}>
                <HelloWorldView />
            </helloWorldContext.Provider>
        );

        expect(await wrapper.queryByText("1.2.0")?.textContent).toEqual("1.2.0")
    })

    test("click must call changeVersion",async () => {
        // arrange
        const ds = new HelloWorldDS()
        let changeVersion = jest.spyOn(ds,'changeVersion').mockImplementation(() => {});
        const controller = new HelloWorldController(new HelloWorldDI(),ds);

        // act
        render(
            <helloWorldContext.Provider value={{ store: controller }}>
                <HelloWorldView />
            </helloWorldContext.Provider>
        );
        fireEvent.click(screen.getByText('Upgrade button'))

        // assert
        expect(changeVersion).toHaveBeenCalledTimes(1);
        changeVersion.mockRestore();
    })
})

特别感谢Garrett Motzner