roo*_*mer 2 unit-testing reactjs jestjs
我对 javascript、react 和玩笑很陌生。我想模拟一个将作为上下文值传递的函数。我能够传递模拟函数,并且能够看到模拟函数被触发,但是当我尝试检查模拟以断言结果时。我收到错误,附在下面。
这是我要测试的课程:
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;
Run Code Online (Sandbox Code Playgroud)
这是我的测试:
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);
});
Run Code Online (Sandbox Code Playgroud)
这是测试结果:
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>
Run Code Online (Sandbox Code Playgroud)
我看到模拟功能被触发。但模拟的状态没有更新。我在这里做错了什么?
和范围有关系吗?我尝试在 act 块之外调用模拟函数,并且该状态已更新为模拟。当相同的调用发生在块内时,它不起作用。
那么异步就是这里的问题。我开始使用很棒的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);
});
});
Run Code Online (Sandbox Code Playgroud)
renderWithContextAndRouter是一个注入我的上下文和路由的 HOC。我的实际测试甚至没有这种验证,因为这些只是实现细节。这只是为了帮助一些初学者:)
| 归档时间: |
|
| 查看次数: |
3410 次 |
| 最近记录: |