Javascript 如何存根fs回调';s注入参数以消除在测试套件中接触文件系统的需要?

Javascript 如何存根fs回调';s注入参数以消除在测试套件中接触文件系统的需要?,javascript,node.js,asynchronous,stub,sinon,Javascript,Node.js,Asynchronous,Stub,Sinon,我正在使用Chai、Mocha和Sinon作为我的测试框架 现在,我有一个测试,但实际上我必须创建一个目录,并将文件放入其中,以使我的测试能够真正执行某些操作(这将是一个大型测试套件,所以至少可以说,使用所有这些diskIO执行操作并不理想)。我怎样才能去掉注入机制,这样我就不必在测试中接触磁盘了 在下面的示例代码中,我正在考虑某种方式来存根fs.readdir方法注入的err和文件参数。这样,我就避免了在单元测试中测试fs.readdir。我在谷歌上搜索了一下API文档,但没有找到我需要的(或

我正在使用Chai、Mocha和Sinon作为我的测试框架

现在,我有一个测试,但实际上我必须创建一个目录,并将文件放入其中,以使我的测试能够真正执行某些操作(这将是一个大型测试套件,所以至少可以说,使用所有这些diskIO执行操作并不理想)。我怎样才能去掉注入机制,这样我就不必在测试中接触磁盘了

在下面的示例代码中,我正在考虑某种方式来存根fs.readdir方法注入的
err
文件
参数。这样,我就避免了在单元测试中测试fs.readdir。我在谷歌上搜索了一下API文档,但没有找到我需要的(或者没有认出它)

下面是我所说的一些示例代码:

正在测试的功能 样本测试用例
一种方法是这样构造模块:

var Example = function (fs) {
  fs = fs || require('fs');

  this.fsFxnWrapper = function(dir, callback) {
    var doSomeMutation = function (files) {
      ...
    };

    fs.readdir(dir, function(err, files) {
      callback(err, doSomeMutation(files));
    });
  }
};

module.exports = Example;
然后,您可以在将其传递到模块的构造函数之前模拟
fs

describe('When the directory has things'', function () {
  it('should do the proper mutation on the files list', function () {

    var Example = require('Example');
    var fs = require('fs');

    fs.readir = function () {
      // your alternative implementation that doesn't touch the filesystem
    }

    var example = new Example(fs);
    var valueAfterMutation = [ /* the expected answer */];

    example.fsFxnWrapper('test/dir', function (err, files) {
      expect(files).to.deep.equal(valueAfterMutation);
      expect(err).to.equal(null);
    });
  });
});
不过,我很想听听其他人对此的看法,因为我已经在一些地方使用过这种方法,虽然它有效,但我不确定是否存在更理想的解决方案


希望有帮助。

如果你在NoDE.js下工作,你可能会考虑一些嘲弄的库:

是唯一的答案,把DOMMOMETUTION函数拉出来,这样它就可以与FSFXNWRAPER的其他部分隔离开来测试了。我来看看这些。我一直在阅读Sinon的文档,因为这似乎很流行,但可能node mock会针对这个特定的用例提供一些内容。浏览这些文档后,node mock看起来不是很成熟或活跃,但mock fs可能适用于这个特定的实例。Sinon是一个强大的通用mock库。SInon.mock是一个方便的工具,您可以使用它创建自己的mock。但是,您仍然需要自己创建它来提供一些活动。上面提到的库为您提供了特定对象/服务/api的模拟。它们不是通用的,但可以处理精确的任务。当使用
fs
模块中的多个函数时,我发现自己越来越多地模仿
fs
模块,并在这个过程中越来越多地了解其内部结构。在这里,使用库更有意义。我认为这肯定比把东西放在磁盘上然后清理好。我注意到这(把东西放在磁盘上)在我的测试套件中产生了并发问题,这是行不通的。
var Example = function (fs) {
  fs = fs || require('fs');

  this.fsFxnWrapper = function(dir, callback) {
    var doSomeMutation = function (files) {
      ...
    };

    fs.readdir(dir, function(err, files) {
      callback(err, doSomeMutation(files));
    });
  }
};

module.exports = Example;
describe('When the directory has things'', function () {
  it('should do the proper mutation on the files list', function () {

    var Example = require('Example');
    var fs = require('fs');

    fs.readir = function () {
      // your alternative implementation that doesn't touch the filesystem
    }

    var example = new Example(fs);
    var valueAfterMutation = [ /* the expected answer */];

    example.fsFxnWrapper('test/dir', function (err, files) {
      expect(files).to.deep.equal(valueAfterMutation);
      expect(err).to.equal(null);
    });
  });
});