问题描述
我正在尝试对一个看起来像这样的模块进行单元测试
import { Countdown } from "./database/orm";
export class PersistentTimer {
protected constructor(...) { ... }
// This object requires writing to a database,so I protect the constructor and
// force construction through an async interface
public static async create(...) {
const entity = new Countdown();
// do stuff
await entity.save();
return new PersistentTimer(entity);
}
}
我正在 mocha 生态系统中寻找类似 jest.mock
的东西来模拟 Countdown 模块,因为它有副作用,以便我可以对这个模块进行单元测试。 Sinon 似乎只处理传递给函数调用的函数、对象的属性或对象实例。
解决方法
您可以使用 link seams 存根 ./database/orm
模块。
这是 CommonJS 版本,因此我们将使用 proxyquire 来构建接缝。
例如
main.ts
:
import { Countdown } from './database/orm';
export class PersistentTimer {
protected constructor(entity: Countdown) {}
public static async create() {
const entity = new Countdown();
await entity.save();
return new PersistentTimer(entity);
}
}
main.test.ts
:
import sinon from 'sinon';
import proxyquire from 'proxyquire';
import { expect } from 'chai';
describe('65399764',() => {
it('should pass',async () => {
const countdownInstanceStub = {
save: sinon.stub(),};
const CountdownStub = sinon.stub().returns(countdownInstanceStub);
const { PersistentTimer } = proxyquire('./main.ts',{
'./database/orm': {
Countdown: CountdownStub,},});
const persistentTimer = await PersistentTimer.create();
sinon.assert.calledOnce(CountdownStub);
sinon.assert.calledOnce(countdownInstanceStub.save);
expect(persistentTimer).to.be.instanceOf(PersistentTimer);
});
});
单元测试结果:
65399764
✓ should pass (1848ms)
1 passing (2s)
-------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-------------------|---------|----------|---------|---------|-------------------
All files | 85.71 | 100 | 66.67 | 85.71 |
65399764 | 100 | 100 | 100 | 100 |
main.ts | 100 | 100 | 100 | 100 |
65399764/database | 50 | 100 | 0 | 50 |
orm.ts | 50 | 100 | 0 | 50 | 3
-------------------|---------|----------|---------|---------|-------------------