如何使用Sinon.js对依赖项注入类进行存根?

问题描述 投票:0回答:1

我有一个名为ReportHandler的类,它依赖于其他类(ReportServiceS3Handlere),像这样:

  • S3Handler:用于将文件上传到S3的类
  • [ReportService:正在对数据库执行CRUD

handleReportAsync是从S3下载文件,执行一些逻辑并将文件更新到数据库的功能。

export class ReportHandler {
  private s3Handler;
  private reportService;

  public constructor(reportService) {
    this.reportService = reportService;;

    const accessKey = process.env.AWS_ACCESS_KEY;
    const secretKey = process.env.AWS_SECRET_ACCESS_KEY;
    const bucketName = process.env.AWS_BUCKET_NAME;
    this.s3Handler = new S3Handler(accessKey, secretKey, bucketName);
  }
  public async handleReportAsync(report) {
    try {
      const data = await this.s3Handler.downloadFile(report.id);
      // do some logic
      reportService.updateFile(report.id, data.Body);
    } catch (error) {
    }
  }
}

我想测试是否调用了reportService.updateFile(),因此我将使用spy来完成此任务。

[显然,我不想从S3下载真实文件,因此,如何用this.s3Handler.downloadFile()存根Sinon.js函数。这是我的尝试,但没有成功。

describe("ReportHandler", () => {
  describe("handleReportAsync", () => {
    let sandbox;
    beforeEach(() => {
      sandbox = Sinon.createSandbox();
    });

    afterEach(() => {
      sandbox.restore();
    });
    it("should call updateFile() function", async () => {
      const report = new Report(faker.random.uuid());
      sandbox.stub(S3Handler.prototype, "downloadFile").callsFake(
        (id)  => {},
      );

      sandbox.stub(ReportService.prototype, "updateFile").callsFake(
        (id, file) => {},
      );
      const reportHandler = new ReportHandler(new ReportService());
      const spy = Sinon.spy(ReportService.prototype, "updateFile");
      await reportHandler.handleReportAsync(report);
      expect(spy.called).to.be.true;
    });
  });
});

欢迎任何意见!预先感谢。

node.js unit-testing dependency-injection sinon stub
1个回答
0
投票
这里是单元测试解决方案:

reportHandler.ts

import S3Handler from "./s3Handler"; export class ReportHandler { private s3Handler; private reportService; public constructor(reportService) { this.reportService = reportService; const accessKey = process.env.AWS_ACCESS_KEY; const secretKey = process.env.AWS_SECRET_ACCESS_KEY; const bucketName = process.env.AWS_BUCKET_NAME; this.s3Handler = new S3Handler(accessKey, secretKey, bucketName); } public async handleReportAsync(report) { try { const data = await this.s3Handler.downloadFile(report.id); this.reportService.updateFile(report.id, data.Body); } catch (error) {} } }

s3Handler.ts

export default class S3Handler { constructor(accessKey, secretKey, bucketName) {} }

reportHandler.test.ts

import { ReportHandler } from "./reportHandler"; import sinon from "sinon"; describe("59766312", () => { let sandbox; beforeEach(() => { sandbox = sinon.createSandbox(); }); afterEach(() => { sandbox.restore(); }); describe("#handleReportAsync", () => { it("should update file", async () => { const reportServiceStub = { updateFile: sandbox.stub() }; const s3Handler = require("./s3Handler"); const downloadFileStub = sandbox.stub().resolves({ Body: "a" }); const s3HandlerInstanceStub = { downloadFile: downloadFileStub }; const s3HandlerStub = sandbox.stub(s3Handler, "default").callsFake(() => s3HandlerInstanceStub); const reportHandler = new ReportHandler(reportServiceStub); const report = { id: 1 }; await reportHandler.handleReportAsync(report); sandbox.assert.calledOnce(s3HandlerStub); sandbox.assert.calledWithExactly(s3HandlerInstanceStub.downloadFile, 1); sandbox.assert.calledWithExactly(reportServiceStub.updateFile, 1, "a"); }); }); });

带有覆盖率报告的单元测试结果:

59766312 #handleReportAsync ✓ should update file 1 passing (12ms) -----------------------|----------|----------|----------|----------|-------------------| File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s | -----------------------|----------|----------|----------|----------|-------------------| All files | 100 | 100 | 90.91 | 100 | | reportHandler.test.ts | 100 | 100 | 100 | 100 | | reportHandler.ts | 100 | 100 | 100 | 100 | | s3Handler.ts | 100 | 100 | 50 | 100 | | -----------------------|----------|----------|----------|----------|-------------------|

源代码:https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/59766312
© www.soinside.com 2019 - 2024. All rights reserved.