reactjs - 反应waitforelement不适用于异步调用
问题描述
我目前正在尝试使用 TypeScript 和类在 React 中进行异步调用的简单登录表单。我的组件如下所示:
import * as React from 'react';
import { LoginService } from './services/LoginService';
interface CredentialsState {
userName: string,
password: string,
isLoggedIn: boolean,
loginAttempted: boolean
}
interface CustomEvent {
target: HTMLInputElement
}
export class Login extends React.Component<{}, CredentialsState> {
state: CredentialsState = {
password: "",
userName: "",
isLoggedIn: false,
loginAttempted: false
};
private loginService: LoginService = new LoginService();
private async handleSubmit(event: React.SyntheticEvent) {
event.preventDefault();
const loginResponse = await this.loginService.login(
this.state.userName,
this.state.password
);
console.log('Login result ' + loginResponse);
this.setState({
loginAttempted: true,
isLoggedIn: loginResponse
});
}
private setPassword(event: CustomEvent) {
this.setState({ password: event.target.value });
}
private setUserName(event: CustomEvent) {
this.setState({ userName: event.target.value });
}
render() {
let loginLabel;
if (this.state.loginAttempted) {
if (this.state.isLoggedIn) {
loginLabel = <label>Login successful</label>
} else {
loginLabel = <label>Login failed</label>
}
}
return (
<div>
<form data-test="login-form" onSubmit={e => this.handleSubmit(e)}>
<input data-test="login-input" name="login" value={this.state.userName} onChange={e => this.setUserName(e)} /><br />
<input data-test="password-input" name="password" value={this.state.password} onChange={e => this.setPassword(e)} type="password" /><br />
<input data-test="submit-button" type="submit" value="Login" /><br />
</form>
{loginLabel}
</div>
)
}
}
它工作得很好,但我也想使用@testing-library/react 测试它我的测试看起来像这样:
import { fireEvent, waitForElement } from '@testing-library/react';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { act } from 'react-dom/test-utils';
import { Login } from './login';
import { LoginService } from './services/LoginService';
describe('Login component tests', () => {
let container: HTMLDivElement;
const loginServiceSpy = jest.spyOn(LoginService.prototype, 'login');
beforeEach(() => {
container = document.createElement('div');
document.body.appendChild(container);
act(() => {
ReactDOM.render(<Login />, container);
});
})
afterEach(() => {
document.body.removeChild(container as HTMLDivElement);
container.remove();
});
it('renders correctly status label', async () => {
loginServiceSpy.mockResolvedValueOnce(false);
const button = container.querySelectorAll('input')[2];
fireEvent.click(button);
const label = await waitForElement(() => {
container.querySelector('label');
}); // THIS query times out and test fails
expect(label).toBeInTheDocument();
});
});
我怎样才能使这个异步测试工作?如果没有异步功能,则container.querySelector('label')可以工作。谢谢!
解决方案
我自己想通了。我在滥用 waitForElement。正确的使用方法是:
const label = await waitForElement(() =>
container.querySelector('label')
)
推荐阅读
- python - H2O DistributedRandomForest 所有树预测
- android - 使用对话框打开另一个应用程序 - 可以吗?
- javascript - JavaScript URL 正则表达式拆分
- java - 无法让 Java Hadoop 库在 Intellij 中工作
- sql - 在 Informix SQL 中将 3 个查询合二为一
- python - 对不同集群的特征进行分析和排序
- c - 打包一个结构会不会错位相邻的内存?
- python - python MongoDB Compass .command() 用户
- android - RadioButton 将文本对齐到左侧,将按钮对齐到右侧
- python - Export data from Python to Tableau directly