开玩笑的模拟功能不注册调用

时间:2019-02-21 10:32:56

标签: javascript reactjs jestjs axios

我有一个带有请求我的api方法的react组件。 出于测试目的,我模拟了模块axiosJest确实使用get识别了第一个呼叫,但不能识别 第二个是post,除非它在get语句之前声明。我可以 记录axios.post.mock.result在我的react组件中有一个价值承诺。 在我的测试中,它是空的。 我这样隔离问题:

我的组件方法

import axios from 'axios';

async getData(data) {
	let response = await axios.get('/api',
		{
			params: {
				data
			}
		});
	if (response.status === 200) {
		response = await axios.post('/api',
			response.data
		);
		if (response.status === 200) {
			this.setState({ data: true });
		}
	}
}

render() {
  if (!this.state.data) {
    return (
    <button 
    onClick={() => this.getData(this.state.input)}
    >Click me</button>)
  } else {
    return (<p>Success</p>);
}

测试

import {render, fireEvent} from 'react-testing-library';
import axios from 'axios';
import App from '../App';

jest.mock('axios');

axios.get.mockResolvedValue({ status: 200, data: { hello: 'world' } });
axios.post.mockResolvedValue({ status: 200 });

test('Component uses axios', () => {
	let app = render(<App />);
	fireEvent.click(app.getByText('Click me'));
	expect(axios.get).toBeCalled();
	expect(axios.post).toBeCalled();
});

1 个答案:

答案 0 :(得分:0)

react-testing-library主要用于黑盒功能测试,不适合测试实现。常见的测试策略是模拟点击并声明DOM:

const { getByText } = render(<App />);
fireEvent.click(app.getByText('Click me'));
await waitForElement(() => getByText('Success'));

可以通过实现断言来强制实施测试。 axios.post被异步调用,并且返回的承诺应该被链接:

...
fireEvent.click(app.getByText('Click me'));
expect(axios.get).toBeCalledTimes(1);
await axios.get.mock.results[0].value;
expect(axios.post).toBeCalledTimes(1);
await waitForElement(() => getByText('Success'));