组件代码:
constructor(props) {
super(props);
this.handleAuthentication = this.handleAuthentication.bind(this);
this.state = {
validAuthCode: true,
}
}
async handleAuthentication(e) {
e.preventDefault();
try {
let validAuthCode = await createPermanentAuth(this.state.authCode);
if (validAuthCode) {
this.props.history.push("/");
}
this.setState({ validAuthCode: false });
} catch(e) {
// error handling
}
}
render() {
return (
<form onSubmit={this.handleAuthentication.bind(this)} data-testid="create-permanent-auth">
<label htmlFor="code">Auth code:</label>
<input id="code"
name="code"
placeholder="12345"
className={this.state.validAuthCode ? 'valid-data' : 'invalid-data'}
onChange={this.handleAuthCodeChange.bind(this)} />
<input type="submit" value="Submit" />
</form>
);
}
测试:
jest.mock('../yasClient');
.
.
import { createPermanentAuth } from '../yasClient';
beforeEach(() => {
token = screen.getByLabelText('Auth code:');
expect(screen.queryByTestId('bad-code-message').classList.contains('hidden')).toBe(true);
});
it("shows authcode outlined in red and error message displayed, when bad token entered.", () => {
createPermanentAuth.mockReturnValueOnce(false);
fireEvent.change(token, { target: { value: '1' } });
fireEvent.submit(screen.getByTestId('create-permanent-auth'));
expect(createPermanentAuth).toHaveBeenCalledTimes(1);
expect(token.classList.contains('invalid-data')).toBe(true);
expect(screen.getByTestId('bad-code-message').classList.contains('visible')).toBe(true);
});
无论出于何种原因,看起来validAuthCode
都不会设置为false。
token.classList.contains('valid-data')
返回true,我希望token.classList.contains('invalid-data')
返回true。
我想知道我是否想念一些东西。我猜测问题可能与异步性和/或setState的调用方式有关。
答案 0 :(得分:0)
您需要在发生这种火灾事件时将更新状态包装起来:
await act(async()=>{
await fireEvent.change(token, { target: { value: '1' } });
fireEvent.submit(screen.getByTestId('create-permanent-auth'));
})
await act(async ()=>Promise.reslove())
这确保您正在测试真实行为。
注意:此处我为令牌组件上的await
添加了fireEvent
,因为我不希望按钮在令牌事件更新状态之前触发submit event
。
答案 1 :(得分:0)
最终花钱在codementor上以得到这个答案。
测试用例
c(Q01, Q02)
beforeEach
it("navigates to '/', when a good token is entered.", async() => {
createPermanentAuthSpy.mockImplementationOnce(() => Promise.resolve(true));
await act(async() => {
await fireEvent.change(token, { target: { value: '1' } });
fireEvent.submit(screen.getByTestId('create-permanent-auth'));
});
expect(createPermanentAuthSpy).toHaveBeenCalledTimes(1);
expect(token.classList.contains('valid-data')).toBe(true);
expect(screen.queryByTestId('bad-code-message').classList.contains('hidden')).toBe(true);
});
我不确定我所拥有的模拟技术与它之间有什么区别-但这可以工作。