Javascript Mocha/Sinon 将 XMLHttpRequest 伪造到测试方法中间的 return 对象
Javascript Mocha/Sinon fake XMLHttpRequest to return object in middle of tested method
你好,我刚开始使用 mocha/sinon,我遇到了这个问题
我正在测试这个方法
export async function onConfigEvent(event: configEvent, otherConfig: otherConfig) {
var myConfig = event.config as Config;
const info = await fetchInfo(otherConfig.detailsPath, myConfig.Id);
if (!isDefined(info)) {
console.log('info is undefined.');
return;
}
}
这个方法实际上要大得多,有很多 if 语句,所以我想测试它的每条路径。我遇到的问题是 fetchInfo()
调用。此函数将调用一个创建 url 的函数,依此类推,然后调用另一个函数,以承诺进行实际调用。我需要做的是伪造这个 fetchInfo
并使它成为 return 我想要的这个实例 我想要它 return undefined
所以它进入 if 并且在其他情况下我想要它到 return 一个伪造的模型,就像它成功了一样。但我不知道该怎么做,我已经搜索了很长时间并开始尝试使用 sinon.stub
但我将如何在这里实现它?
到目前为止我的测试是这样的
it('should log info undefined', () => {
let event: configEvent = {
type: events.Config,
config: { ["Id"]: 361 }
}
let fetch = sinon.stub(fetchResource);
let otherConfig = getOtherConfig();
let spy = sinon.spy(console, 'log');
onConfigEvent(event, otherConfig)
assert(spy.calledWith('info is undefined.'));
spy.restore();
});
其中 fetchResource
是 fetchInfo
调用的函数,但它什么都不做
您需要存根 fetchInfo
函数。 sinon.js 不支持直接存根独立函数。需要使用 rewire 包。
例如
index.ts
:
function isDefined(obj) {
return typeof obj !== 'undefined';
}
export async function fetchInfo(url, id) {
//
}
export async function onConfigEvent(event, otherConfig) {
const myConfig = event.config;
const info = await fetchInfo(otherConfig.detailsPath, myConfig.Id);
if (!isDefined(info)) {
console.log('info is undefined.');
return;
}
}
index.test.ts
:
import rewire from 'rewire';
import sinon from 'sinon';
describe('60828989', () => {
afterEach(() => {
sinon.restore();
});
it('should print log if info is undefined', async () => {
const mod = rewire('./');
const fetchInfoStub = sinon.stub().resolves();
const logSpy = sinon.spy(console, 'log');
mod.__set__('fetchInfo', fetchInfoStub);
const event = { config: { id: 1 } };
const otherConfig = { detailsPath: 'http:/localhost' };
await mod.onConfigEvent(event, otherConfig);
sinon.assert.calledWithExactly(logSpy, 'info is undefined.');
});
it('should do nothing if info is defined', async () => {
const mod = rewire('./');
const fetchInfoStub = sinon.stub().resolves({});
const logSpy = sinon.spy(console, 'log');
mod.__set__('fetchInfo', fetchInfoStub);
const event = { config: { id: 1 } };
const otherConfig = { detailsPath: 'http:/localhost' };
await mod.onConfigEvent(event, otherConfig);
sinon.assert.notCalled(logSpy);
});
});
带有覆盖率报告的单元测试结果:
60828989
info is undefined.
✓ should print log if info is undefined (124ms)
✓ should do nothing if info is defined
2 passing (150ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 66.67 | 100 |
index.ts | 100 | 100 | 66.67 | 100 |
----------|---------|----------|---------|---------|-------------------
源代码:https://github.com/mrdulin/expressjs-research/tree/master/src/Whosebug/60828989
你好,我刚开始使用 mocha/sinon,我遇到了这个问题
我正在测试这个方法
export async function onConfigEvent(event: configEvent, otherConfig: otherConfig) {
var myConfig = event.config as Config;
const info = await fetchInfo(otherConfig.detailsPath, myConfig.Id);
if (!isDefined(info)) {
console.log('info is undefined.');
return;
}
}
这个方法实际上要大得多,有很多 if 语句,所以我想测试它的每条路径。我遇到的问题是 fetchInfo()
调用。此函数将调用一个创建 url 的函数,依此类推,然后调用另一个函数,以承诺进行实际调用。我需要做的是伪造这个 fetchInfo
并使它成为 return 我想要的这个实例 我想要它 return undefined
所以它进入 if 并且在其他情况下我想要它到 return 一个伪造的模型,就像它成功了一样。但我不知道该怎么做,我已经搜索了很长时间并开始尝试使用 sinon.stub
但我将如何在这里实现它?
到目前为止我的测试是这样的
it('should log info undefined', () => {
let event: configEvent = {
type: events.Config,
config: { ["Id"]: 361 }
}
let fetch = sinon.stub(fetchResource);
let otherConfig = getOtherConfig();
let spy = sinon.spy(console, 'log');
onConfigEvent(event, otherConfig)
assert(spy.calledWith('info is undefined.'));
spy.restore();
});
其中 fetchResource
是 fetchInfo
调用的函数,但它什么都不做
您需要存根 fetchInfo
函数。 sinon.js 不支持直接存根独立函数。需要使用 rewire 包。
例如
index.ts
:
function isDefined(obj) {
return typeof obj !== 'undefined';
}
export async function fetchInfo(url, id) {
//
}
export async function onConfigEvent(event, otherConfig) {
const myConfig = event.config;
const info = await fetchInfo(otherConfig.detailsPath, myConfig.Id);
if (!isDefined(info)) {
console.log('info is undefined.');
return;
}
}
index.test.ts
:
import rewire from 'rewire';
import sinon from 'sinon';
describe('60828989', () => {
afterEach(() => {
sinon.restore();
});
it('should print log if info is undefined', async () => {
const mod = rewire('./');
const fetchInfoStub = sinon.stub().resolves();
const logSpy = sinon.spy(console, 'log');
mod.__set__('fetchInfo', fetchInfoStub);
const event = { config: { id: 1 } };
const otherConfig = { detailsPath: 'http:/localhost' };
await mod.onConfigEvent(event, otherConfig);
sinon.assert.calledWithExactly(logSpy, 'info is undefined.');
});
it('should do nothing if info is defined', async () => {
const mod = rewire('./');
const fetchInfoStub = sinon.stub().resolves({});
const logSpy = sinon.spy(console, 'log');
mod.__set__('fetchInfo', fetchInfoStub);
const event = { config: { id: 1 } };
const otherConfig = { detailsPath: 'http:/localhost' };
await mod.onConfigEvent(event, otherConfig);
sinon.assert.notCalled(logSpy);
});
});
带有覆盖率报告的单元测试结果:
60828989
info is undefined.
✓ should print log if info is undefined (124ms)
✓ should do nothing if info is defined
2 passing (150ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 66.67 | 100 |
index.ts | 100 | 100 | 66.67 | 100 |
----------|---------|----------|---------|---------|-------------------
源代码:https://github.com/mrdulin/expressjs-research/tree/master/src/Whosebug/60828989