Kem*_*dan 27 automated-tests unit-testing mocha.js node.js sinon
考虑以下示例Javascript代码:
function privateFunction (time) {
if (time < 12) { console.log('Good morning'); }
if (time >= 12 && time <19) { console.log('Good afternoon'); }
else { console.log('Good night!'); }
};
Run Code Online (Sandbox Code Playgroud)
我应该如何使用mocha(也可能是sinonjs)对nodejs进行单元测试,注意到这是一个在模块内部调用的私有函数?我需要传入参数并检查函数是否正在将正确的东西记录到控制台.
我可以用console.warn和console.error吗?
rob*_*lep 33
我更喜欢mocha-sinon"普通"的sinon,因为它与Mocha完美融合.
例:
var expect = require('chai').expect;
require('mocha-sinon');
// Function to test, can also be in another file and as long as it's
// being called through some public interface it should be testable.
// If it's not in any way exposed/exported, testing will be problematic.
function privateFunction (time) {
if (time < 12) { console.log('Good morning'); }
if (time >= 12 && time <19) { console.log('Good afternoon'); }
else { console.log('Good night!'); }
}
describe('privateFunction()', function() {
beforeEach(function() {
this.sinon.stub(console, 'log');
});
it('should log "Good morning" for hours < 12', function() {
privateFunction(5);
expect( console.log.calledOnce ).to.be.true;
expect( console.log.calledWith('Good morning') ).to.be.true;
});
it('should log "Good afternoon" for hours >= 12 and < 19', function() {
privateFunction(15);
expect( console.log.calledOnce ).to.be.true;
expect( console.log.calledWith('Good afternoon') ).to.be.true;
});
it('should log "Good night!" for hours >= 19', function() {
privateFunction(20);
expect( console.log.calledOnce ).to.be.true;
expect( console.log.calledWith('Good night!') ).to.be.true;
});
});
Run Code Online (Sandbox Code Playgroud)
一个潜在的问题:一些Mocha记者也使用console.log它,因此存在它的测试可能不会产生任何输出.
有一种解决方法,但它也不理想,因为它会散布Mocha输出和输出privateFunction().如果这不是问题,请替换beforeEach()为:
beforeEach(function() {
var log = console.log;
this.sinon.stub(console, 'log', function() {
return log.apply(log, arguments);
});
});
Run Code Online (Sandbox Code Playgroud)
忽略它是一个私有函数的事实,我会采取几个步骤;重构我的代码以更好地分离关注点,并将这种分离与测试替身结合使用。
将所有副作用带到它们自己的模块之外(这里的副作用是写入控制台):
输出.js
function log (message) {
console.log(message);
};
module.exports = {log};
Run Code Online (Sandbox Code Playgroud)
应用程序.js
const {log} = require('out');
function greeter (time) {
if (time < 12) {
log('Good morning');
}
if (time >= 12 && time < 19) {
log('Good afternoon');
} else {
log('Good night!');
}
};
module.exports = {greeter};
Run Code Online (Sandbox Code Playgroud)在测试时使用一些模块代理/间谍,例如proxyquire来替换整个编写器:
应用程序规范.js
describe('output writers', function(){
const fakeOut = {
log: sinon.spy(),
};
const app = proxyquire('./app', {
'out': fakeOut
});
it('should log to the fake out', function(){
app.greeter(15);
assert(fakeOut.log.calledOnce);
});
});
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
33886 次 |
| 最近记录: |