node.js - InversifyJS 联合测试 sinon stub
问题描述
我正在尝试在我的InversifyJS
项目上编写单元测试代码。路线测试(使用supertest
)工作正常。然后尝试编写sinon
stub
,spy
测试,但无法成功。我的示例代码如下:
演示路线
@injectable()
class DemoRoute implements IDemoRoute {
private _demoController:IDemoController;
constructor( @inject(TYPES.IDemoController) demoController:IDemoController ) {
this._demoController = demoController;
}
create(req: Request, res: Response, next: NextFunction) {
return this._demoController.create(req.body)
}
}
演示.test.ts
import "reflect-metadata";
import * as sinon from "sinon";
const sandbox = sinon.createSandbox();
describe.only("Demo Spec 2", () => {
demoController = container.get<IDemoController>(TYPES.IDemoController);
beforeEach((done) => {
insertStub = sandbox.stub(demoController, 'create');
done();
});
afterEach(() => {
sandbox.restore();
});
it("Should call demo route url", async done => {
demoRoute = container.get<IDemoRoute>(TYPES.IDemoRoute);
const stub = insertStub.returns(Promise.resolve({ body: { name: "test xyz", code: "test abc"} }));
const result = await demoRoute.create({body: demoData.validData}, {send: (params) => params});
expect(stub).to.have.been.called; // throw error
done();
});
}
单元测试出错
UnhandledPromiseRejectionWarning: AssertionError: 预期 create 至少被调用过一次,但它从未被调用过
我怎么解决这个问题?提前致谢。
解决方案
我们能够通过对从 inversify 容器中提取的实例的方法进行存根,并使用sinon.createStubInstance()
模拟构造函数来使存根工作。看起来像这样:
describe.only("Demo Spec 2", () => {
demoController = container.get<IDemoController>(TYPES.IDemoController);
demoControllerStub = sinon.createStubInstance(IDemoController) as SinonStubbedInstance<IDemoController>;
beforeEach((done) => {
insertStub = sinon.stub(demoController, 'create');
done();
});
afterEach(() => {
sandbox.restore();
});
it("Should call demo route url", async done => {
demoRoute = container.get<IDemoRoute>(TYPES.IDemoRoute);
const stub = insertStub.returns(Promise.resolve({ body: { name: "test xyz", code: "test abc"} }));
const result = await demoRoute.create({body: demoData.validData}, {send: (params) => params});
expect(demoControllerStub.create.calledOnce);
done();
});
}
我更喜欢的另一种对我们有用的方法是存根实例并取消绑定并将存根实例绑定到容器。看起来像这样:
describe.only("Demo Spec 2", () => {
demoControllerStub = sinon.createStubInstance(IDemoController);
container.unbind(IDemoController);
container.bind(IDemoController).toConstantValue(demoControllerStub);
beforeEach((done) => {
demoControllerStub.create.reset();
done();
});
it("Should call demo route url", async done => {
demoRoute = container.get<IDemoRoute>(TYPES.IDemoRoute);
const stub = insertStub.returns(Promise.resolve({ body: { name: "test xyz", code: "test abc"} }));
const result = await demoRoute.create({body: demoData.validData}, {send: (params) => params});
sinon.assert.calledWith(demoControllerStub.create, sinon.match({body: demoData.validData});
done();
});
}
推荐阅读
- c# - 我实现了在接口中声明的泛型方法,但出现错误
- java - 如何使用 Stream 读取由 newLine 分隔的整数?
- linq - LINQ:在 DbSet 中按时间比较超时
。在哪里() - python - 使用 SQL 从特定日期选择活动
- c# - System.NullReferenceException 在 Microsoft.Office.Tools.Ribbon.RibbonBase.Dispose(布尔)
- java - 如何在其他活动中编辑相同的对象
- python - Python - 我想以 10 年的间隔分组并将其合并回来
- java - Spring boot Kafka 不起作用 - 消费者未收到消息
- windows - Ansible - 如何将域组作为变量
- excel - 如何编写一个公式以生成固定数量的连续数字行?