Node.js Sinon.js提供的带参数的间谍函数

Node.js Sinon.js提供的带参数的间谍函数,node.js,unit-testing,mocking,sinon,typeorm,Node.js,Unit Testing,Mocking,Sinon,Typeorm,我正在尝试编写一些代码的单元测试,这些测试使用typeorm而不影响数据库。 我用sinon做间谍/存根/模拟。 这是我的职责 异步更新AliedWithLock(queryRunner:queryRunner):承诺{ 等待queryRunner.manager .getRepository(报告) .createQueryBuilder(“报告”) .useTransation(true) .setLock(“悲观的写”) .最新情况(报告) .set({status:ReportStatu

我正在尝试编写一些代码的单元测试,这些测试使用typeorm而不影响数据库。 我用sinon做间谍/存根/模拟。 这是我的职责

异步更新AliedWithLock(queryRunner:queryRunner):承诺{
等待queryRunner.manager
.getRepository(报告)
.createQueryBuilder(“报告”)
.useTransation(true)
.setLock(“悲观的写”)
.最新情况(报告)
.set({status:ReportStatus.FAILED})
.where(`(status=“doing”)`)
.execute();
}
我已经编写了一个伪测试,以确保使用spy函数调用
execute()
。 但是我想测试这些函数的参数
createQueryBuilder
…,以确保参数是正确的。 我看了一下sinon文档,似乎sinon通过这个API支持测试参数:
spy().withArgs(arg1,arg2…

但我不知道如何正确地监视我的函数

description(“updatedofailedwithlock()”,():void=>{
让沙盒:Sinon.SinonSandbox;
beforeach(()=>(sandbox=Sinon.createSandbox());
每次之后(()=>沙箱恢复);
它(“应该成功”,异步():Promise=>{
const fakeManager={
getRepository:()=>{
退货假货管理员;
},
createQueryBuilder:()=>{
退货假货管理员;
},
UseTransation:()=>{
退货假货管理员;
},
setLock:()=>{
退货假货管理员;
},
更新:()=>{
退货假货管理员;
},
集合:()=>{
退货假货管理员;
},
其中:()=>{
退货假货管理员;
},
执行:()=>{},
};
常量fakeQueryRunner={
经理:冒牌货经理,
};
const connection=new typeorm.connection({type:“mysql”});
const reportService=new reportService();
sandbox.stub(连接,“createQueryRunner”).callsFake(():any=>{
返回fakeQueryRunner;
});
const queryRunner=connection.createQueryRunner();
constspy=sandbox.spy(fakeManager,“execute”);
reportService.updatedofailedwithlock(queryRunner);
expect(spy.calledOnce).be.true;
});
});

欢迎任何帮助。提前谢谢

我看到了你的代码,有些地方可以改进:

  • 使用
    returnsThis()
    替换
    return fakeManager
  • 调用
    updatedofailedwithlock
description(“updatedofailedwithlock()”,():void=>{
让沙盒:sinon.SinonSandbox;
beforeach(()=>(sandbox=sinon.createSandbox());
每次之后(()=>沙箱恢复);
它(“应该成功”,异步():Promise=>{
//使用returnsThis()
const fakeManager={
getRepository:sandbox.stub().returnsThis(),
createQueryBuilder:sandbox.stub().returnsThis(),
UseTransation:sandbox.stub().returnsThis(),
setLock:sandbox.stub().returnsThis(),
更新:sandbox.stub().returnsThis(),
set:sandbox.stub().returnsThis(),
其中:sandbox.stub().returnsThis(),
执行:sandbox.stub().returnsThis(),
}
常量fakeQueryRunner={
经理:冒牌货经理,
};
const reportService=new reportService();
//在这里等待是很重要的
wait reportService.updatedofailedwithlock(fakeQueryRunner);
expect(fakeManager.execute.calledOnce).to.be.true;
expect(fakeManager.createQueryBuilder.calledWith('report'))to.be.true;
});
});

希望能有所帮助

谢谢你的回答。这看起来不错,但当我运行测试时,我遇到了这个问题:
TypeError:queryRunner.manager.getRepository(…).createQueryBuilder(…).useTransation(…).setLock(…).update(…).set(…).where(…)和where不是一个函数
似乎是您添加的
和where
,这在问题的代码示例中不存在。为了解决这个错误,我们可以在
where
行之后添加
andWhere:sandbox.stub().returnsThis()
describe("updateDoingToFailedWithLock()", (): void => {
  let sandbox: sinon.SinonSandbox;

  beforeEach(() => (sandbox = sinon.createSandbox()));
  afterEach(() => sandbox.restore);

  it("should be success", async (): Promise<void> => {

    // using returnsThis()
    const fakeManager = {
      getRepository: sandbox.stub().returnsThis(),
      createQueryBuilder: sandbox.stub().returnsThis(),
      useTransaction: sandbox.stub().returnsThis(),
      setLock: sandbox.stub().returnsThis(),
      update: sandbox.stub().returnsThis(),
      set: sandbox.stub().returnsThis(),
      where: sandbox.stub().returnsThis(),
      execute: sandbox.stub().returnsThis(),      
    }

    const fakeQueryRunner = {
      manager: fakeManager,
    };

    const reportService = new ReportService();

    // having await here is important
    await reportService.updateDoingToFailedWithLock(fakeQueryRunner);


    expect(fakeManager.execute.calledOnce).to.be.true;
    expect(fakeManager.createQueryBuilder.calledWith('report')).to.be.true;
  });
});