笑话模拟函数被调用。但模拟状态未更新?

时间:2020-06-16 15:02:02

标签: reactjs unit-testing jestjs

我是javascript新手,请开玩笑。我想模拟一个将作为上下文值传递的函数。我能够传递模拟函数,并且无法看到模拟函数已触发,但是当我尝试检查模拟以断言结果时。即时通讯出现错误,附在下面。

这是我要测试的课程:

class Login extends Component {
    constructor(props) {
        super(props);
        this.state = {
            authInProgress: true,
            authSuccess: false
        };
    }

    componentDidMount() {
        if (this.context.isAuthenticated) {
            this.setState({
                authInProgress: false,
                authSuccess: true
            });
        } else {
            isUserLoggedIn().then((response) => {
                this.context.logIn();
                this.setState({
                    authInProgress: false,
                    authSuccess: true
                });
            }).catch((err) => {
                console.log(err);
            });
        }
    }

    render() {
        if (this.state.authInProgress) {
            return <div>Rendering login</div>;
        } else if (this.state.authSuccess) {
            return <Redirect to={ROOT}/>;
        }
    }
}

Login.contextType = Context;

export default Login;

这是我的测试

it("When user is logged In, then update the context and redirect to ROOT.", () => {
    const resp = {
        data: {
            responseCode: 600
        }
    };
    isUserLoggedIn.mockResolvedValue(resp);
    const mockLogIn = jest.fn(() => console.log("im hit"));

    act(() => {
        render(
            <MemoryRouter>
                <Context.Provider value={{isAuthenticated: false, logIn: mockLogIn}}>
                    <Login/>
                </Context.Provider>
            </MemoryRouter>
            , container);
    });
    expect(mockLogIn.mock.calls.length).toBe(1);
});

这是测试结果:

 console.log src/__tests__/auth/components/Login.test.jsx:62
    im hit


Error: expect(received).toBe(expected) // Object.is equality

Expected: 1
Received: 0
<Click to see difference>

我看到模拟功能被触发了。但模拟的状态不会更新。我在这里做错了什么?

与范围有关吗?我尝试在行为块之外调用模拟函数,并将状态更新为模拟。当同一调用在该块内发生时,将无法正常工作。

1 个答案:

答案 0 :(得分:1)

那么异步是这里的问题。我开始使用很棒的react-testing-library并添加了等待测试的时间。然后它按预期工作。

现在我的测试看起来像这样

it("When the user's session is still active (auth tokens are valid), then refresh the tokens and the user is redirected to root.", async () => {
    const resp = {
        data: {
            responseCode: 600
        }
    };
    isUserLoggedIn.mockResolvedValue(resp);
    refreshAuthData.mockImplementation();
    const mockLogin = jest.fn();

    const {history} = renderWithContextAndRouter(
        <Login/>, {
            route: "/login",
            context: {
                isAuthenticated: false,
                logIn: mockLogin
            }
        }
    );
    await waitFor(() => {
        expect(history.location.pathname).toBe("/");
        expect(mockLogin.mock.calls.length).toBe(1);
    });
});

renderWithContextAndRouter是一个HOC,可注入我的上下文和路由。我的实际测试甚至没有此验证,因为这些只是实现细节。这只是为了帮助一些初学者:)

相关问题