jest mock XMLHttpRequest
场景
要开发一个sdk需要请求网络,需要在本地连接远端sdk,这时候有两种方式去模拟这种行为。
- 测试时候通过本地代理,做接口转发
- 通过jest直接mock xhr对象,让其返回一定是那个数据格式
对于第一种来说,还需要更多的接口信息,依赖后端的逻辑判断,为了sdk依赖更小,我选择直接使用mock的方式。
jest mock一个实例
jest
// jest.mock(implementation)是 jest.fn().mockImplementation(implementation)
// 缩写
global.XMLHttpRequest = jest.fn().mockImplementation(()=>{
return {
open:jest.fn(),
send:function(){
setTimeout(()=>{
console.log(this);
this.response = "ok"
this.onload()
})
},
}
})
describe('xhr mock', () => {
/**
* @type {XMLHttpRequest}
*/
let xhr;
beforeEach(() => {
xhr = new XMLHttpRequest();
});
it('should get ok', (done) => {
xhr.open("http://test.com/rest/abc");
xhr.onload= ()=>{
expect(xhr.response).toBe("ok")
done();
}
xhr.send();
});
});
这样我们就成功mock一个xhr接口了,不过现在还是存在问题,不能根据路径返回不同的数据,那么我们继续修改下我们的方法
let mockCache = {};
function mockApi(path,data){
mockCache[path] = data;
}
// jest.mock(implementation)是 jest.fn().mockImplementation(implementation)
// 缩写
global.XMLHttpRequest = jest.fn().mockImplementation(()=>{
return {
open:function(type,path){
this.response = mockCache[path]
},
send:function(){
this.onload()
},
}
})
describe('xhr mock', () => {
/**
* @type {XMLHttpRequest}
*/
let xhr;
beforeEach(() => {
xhr = new XMLHttpRequest();
});
it('should get ok', (done) => {
mockApi("http://test.com/rest/abc","ok")
xhr.open("get","http://test.com/rest/abc");
xhr.onload= ()=>{
expect(xhr.response).toBe("ok")
done();
}
xhr.send();
});
it('should get {abc: 123}', (done) => {
mockApi("http://test.com/rest/abc",{abc:123})
xhr.open("get","http://test.com/rest/abc");
xhr.onload= ()=>{
expect(xhr.response).toStrictEqual({abc:123})
done();
}
xhr.send();
});
});
剩下的还可以继续扩充,但是到了这部分就够我的需求用了。
简单的轮子自己搞,代码简洁又明了。