单位测试承诺与 Mocha Sinon Chai 和 Proxyquire
在这里,我们有一个简单的测试类,它根据外部 ResponseProcessor
的结果返回一个 Promise
,这需要时间来执行。
为了简单起见,我们假设 processResponse
方法永远不会失败。
import {processResponse} from '../utils/response_processor';
const ping = () => {
return new Promise((resolve, _reject) => {
const response = processResponse(data);
resolve(response);
});
}
module.exports = ping;
为了测试这一点,我们可以利用以下工具。
我在 package.json
文件中使用了以下 test
脚本。
"test": "NODE_ENV=test mocha --compilers js:babel-core/register --require ./test/unit/test_helper.js --recursive test/**/*_spec.js"
这允许我使用 es6
语法。它引用了一个看起来像的 test_helper
import chai from 'chai';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import chaiAsPromised from 'chai-as-promised';
import sinonStubPromise from 'sinon-stub-promise';
chai.use(sinonChai);
chai.use(chaiAsPromised);
sinonStubPromise(sinon);
Proxyquire
允许我们在外部 ResponseProcessor
的位置注入我们自己的存根。然后我们可以使用 sinon
监视存根的方法。我们使用了 chai
的扩展,chai-as-promised
注入以检查 ping()
方法的承诺是 fullfilled
,并且 eventually
返回所需的响应。
import {expect} from 'chai';
import sinon from 'sinon';
import proxyquire from 'proxyquire';
let formattingStub = {
wrapResponse: () => {}
}
let ping = proxyquire('../../../src/api/ping', {
'../utils/formatting': formattingStub
});
describe('ping', () => {
let wrapResponseSpy, pingResult;
const response = 'some response';
beforeEach(() => {
wrapResponseSpy = sinon.stub(formattingStub, 'wrapResponse').returns(response);
pingResult = ping();
})
afterEach(() => {
formattingStub.wrapResponse.restore();
})
it('returns a fullfilled promise', () => {
expect(pingResult).to.be.fulfilled;
})
it('eventually returns the correct response', () => {
expect(pingResult).to.eventually.equal(response);
})
});
现在让我们假设你希望测试使用 ping
响应的内容。
import {ping} from './ping';
const pingWrapper = () => {
ping.then((response) => {
// do something with the response
});
}
module.exports = pingWrapper;
为了测试 pingWrapper
我们利用
和以前一样,Proxyquire
允许我们在外部依赖的位置注入我们自己的存根,在这种情况下我们之前测试过的 ping
方法。然后我们可以使用 sinon
监视那个存根的方法,并利用 sinon-stub-promise
来允许我们使用。然后可以在测试中解析或拒绝此承诺,以便测试包装器对此的响应。
import {expect} from 'chai';
import sinon from 'sinon';
import proxyquire from 'proxyquire';
let pingStub = {
ping: () => {}
};
let pingWrapper = proxyquire('../src/pingWrapper', {
'./ping': pingStub
});
describe('pingWrapper', () => {
let pingSpy;
const response = 'some response';
beforeEach(() => {
pingSpy = sinon.stub(pingStub, 'ping').returnsPromise();
pingSpy.resolves(response);
pingWrapper();
});
afterEach(() => {
pingStub.wrapResponse.restore();
});
it('wraps the ping', () => {
expect(pingSpy).to.have.been.calledWith(response);
});
});