代码之家  ›  专栏  ›  技术社区  ›  Xero

Mobx反应测试组件

  •  0
  • Xero  · 技术社区  · 4 年前

    快把我逼疯了。使用useContext测试如何与mobx反应? 我试着用玩笑和酵素,但是当我试着

    export const HelloWorldView = observer(() => {
        const { store } = useHelloWorldController()
        const dataStore = store.datastore
    
        return (
            <>
                <DisplayVersion version={dataStore.versionNumber} />
            </>
        )
    })
    

    以及

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

    但我现在

    jest.mock() 不允许引用任何 超出范围的变量。

    已经用doMock试过了,但根本不起作用

    0 回复  |  直到 4 年前
        1
  •  0
  •   Xero    4 年前

    我已经改变了设置提供者的方式

    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