在我的react-native应用程序中,我想向我的服务器发送一个帖子请求,并根据结果,我想显示一条消息。我想用jest对它进行单元测试,嘲笑后端的调用。
我尝试创建一个最小的示例来显示正在发生的事情:
这是我正在测试的组件
import React from 'react';
import { Alert } from 'react-native';
import { create } from 'apisauce';
const api = create({ baseURL: "someurl" });
export class ApisauceExample extends React.Component {
upload() {
api.post('/upload')
.then(() => { Alert.alert('Success!', 'Thanks, dude!' ); })
.catch(() => { Alert.alert('Error!', 'Something went wrong!' ); });
}
render() {
this.upload();
return null;
}
}
到目前为止,这么容易。让我用单元测试测试正面POST行为,我在模拟模块:
使用全局模拟的工作单元测试:
import React from 'react';
import Adapter from 'enzyme-adapter-react-16';
import { configure, shallow } from 'enzyme';
import { ApisauceExample } from '../src/ApisauceExample';
configure({ adapter: new Adapter() });
const mockAlert = jest.fn();
jest.mock('Alert', () => ({
alert: mockAlert
}));
let mockPostResult = jest.fn();
jest.mock('apisauce', () => ({
create: () => ({
post: (url) => new Promise((resolve) => {
mockPostResult(url);
resolve();
})
})
}));
describe('ApisauceExample', () => {
it('should call create and alert', async () => {
await shallow(<ApisauceExample />);
expect(mockPostResult).toHaveBeenCalledTimes(1);
expect(mockAlert).toHaveBeenCalledWith('Success!', 'Thanks, dude!');
});
});
是的,这完美无缺。但现在,我想测试我的代码在成功的POST和不成功的POST中是否正常运行。我了解到你可以使用mockImplementation
函数通过jest更改模拟。 (参见例如Jest Mock module per test)。
我已经在其他测试中使用过它,但在这里它根本不起作用:
每个测试用例不具有不同模拟行为的单元测试
import React from 'react';
import Adapter from 'enzyme-adapter-react-16';
import { configure, shallow } from 'enzyme';
import { ApisauceExample } from '../src/ApisauceExample';
configure({ adapter: new Adapter() });
const mockAlert = jest.fn();
jest.mock('Alert', () => ({
alert: mockAlert
}));
jest.mock('apisauce', () => ({
create: jest.fn()
}));
import { create } from 'apisauce';
describe('ApisauceExample2', () => {
it('should call create and alert', async () => {
create.mockImplementation(() => ({
post: (url) => new Promise((resolve, reject) => {
reject("error");
})
}));
await shallow(<ApisauceExample />);
expect(mockAlert).toHaveBeenCalledWith('Error!', 'Something went wrong!');
});
});
这导致:
Failed: Cannot read property 'post' of undefined
TypeError: Cannot read property 'post' of undefined
at ApisauceExample.upload (src/ApisauceExample.js:10:4)
at ApisauceExample.render (src/ApisauceExample.js:16:6)
我只是不明白发生了什么。在我看来,第二个模拟与第一个模拟相同(除了拒绝而不是解决)。
你看到这里发生了什么吗?我真的很感激任何提示。
非常感谢,祝你有愉快的一天!
答案 0 :(得分:0)
尝试将axios-mock-adapter
添加到您的设置中,
并记住模拟api.apisauce.axiosInstance
而非API(apisauce通过api.apisauce.axiosInstance
公开内部axios实例
如此:
test('mock adapter', async () => {
const api = API.create()
const mock = new MockAdapter(api.axiosInstance)
mock.onGet('/someEndpoint').reply(201, {
re: 'superstar'
})
const response = await api.getSomeEndpoint()
expect(response.ok).toBe(true)
expect(response.status).toBe(201)
expect(response.data).toEqual({ re: 'superstar' })
})
和您的api
import apisauce from 'apisauce'
...一些代码
const create = (baseURL = 'https://api.github.com/') => {
const api = apisauce.create()
const getSomeEndpoint = () => api.get('some_endpoint')
return {
getSomeEndpoint,
axiosInstance: api.axiosInstance
}
}
export default {
create
}