【问题标题】:Testing functions with properties using Jest and Sinon使用 Jest 和 Sinon 测试具有属性的函数
【发布时间】:2020-06-02 13:32:04
【问题描述】:

我正在尝试编写测试以测试我的应用程序上的流,使用其 createWriteStream 函数处理 fs 库,因此我创建的存根如下:

writeStreamStub = sinon.stub()
onceStreamEventStub = sinon.stub()
endStreamStub = sinon.stub()
onStreamStub = sinon.stub()

createStreamStub = sinon.stub(fs, 'createWriteStream').returns({
  write: writeStreamStub,
  once: onceStreamEventStub,
  end: endStreamStub,
  on: onStreamStub
})

所以现在我可以测试函数是否被调用以及返回的函数是否也被调用。但是我正在使用--coverage 标志,并且没有涵盖返回函数的回调代码,write 方法在process.nextTick 内部被调用,我不知道该怎么做。是否可以涵盖整个代码和回调中的代码,如果可以,我该怎么做。提前致谢。

注意变量是全局声明的

【问题讨论】:

  • 不清楚您的实际问题是什么,或者您在说“如何解决这个问题”时指的是什么。请提供更多详细信息。
  • @RomiHalasz 我想要做的是测试回调函数中的代码,例如现在调用stream.on('error', function () {}) 时,我想开玩笑地查看匿名函数中的代码

标签: node.js jestjs sinon


【解决方案1】:

如果没有充分的理由同时使用 sinon 和 jest,我建议只使用一个库。如果你决定开玩笑,这里有一个简单的例子。假设你有一个像

这样的类
const fs = require('fs');

module.exports = class FileWriter {
  constructor() {
    this.writer = fs.createWriteStream('./testfile.txt');
  }

  writeFile() {
    process.nextTick(() => {
      this.writeContent('hello world');
    });
  }

  writeContent(content) {
    this.writer.write(content);
    this.writer.end();
  }

};

并且在您的单元测试中,您想模拟所有使用的 fs 函数(在本例中为 createWriteStream、writer、end)的行为,并检查它们是否使用正确的参数调用。你可以这样做:

const fs = require('fs');
const FileWriter = require('./FileWriter');
// use this to have mocks for all of fs' functions (you could use jest.fn() instead as well)
jest.mock('fs');
describe('FileWriter', () => {
  it('should write file with correct args', async () => {
    const writeStub = jest.fn().mockReturnValue(true);
    const endStub = jest.fn().mockReturnValue(true);
    const writeStreamStub = fs.createWriteStream.mockReturnValue({
      write: writeStub,
      end: endStub,
    });

    const fileWriter = new FileWriter();
    fileWriter.writeFile();
    await waitForNextTick();
    expect(writeStreamStub).toBeCalledWith('./testfile.txt');
    expect(writeStub).toBeCalledWith('hello world');
    expect(endStub).toHaveBeenCalled();
  });
});

function waitForNextTick() {
  return new Promise(resolve => process.nextTick(resolve));
}

【讨论】:

  • 谢谢,这更清楚了,但考虑到在process.nextTick 内部调用write,它会等待它被调用还是我必须为它做一些额外的步骤等待,如果是,我该怎么做才能让它等待
  • 我已经编辑了示例 - 您确实必须等待下一个刻度完成。可能有比我等待承诺更好的方法来做到这一点,但它应该以这种方式工作。
猜你喜欢
  • 2019-07-27
  • 1970-01-01
  • 2017-09-14
  • 1970-01-01
  • 2019-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-02
相关资源
最近更新 更多