2016-05-21 37 views
0

我想单元测试我构建的模块。 举个什么样子差不多.. MyModule的一个印象:Node.js我应该如何单元测试调用其他函数的函数

function MyModule(...) { 
    var self = this; 
    MyModule.init.call(self, ...); 
} 

util.inherits(MyModule, MySuperModule); 

MyModule.init = function(...) { 
... 
}; 

MyModule.prototype.logic = function(..., done) { 
    calls fnA, fnB, fnC, fnD conditionally 
    done(...) 
}; 

MyModule.prototype.fnA = function(...) { 
... 
}; 

MyModule.prototype.fnB = function(...) { 
... 
}; 

MyModule.prototype.fnC = function(...) { 
... 
}; 

MyModule.prototype.fnD = function(...) { 
... 
}; 

MySuperModule:

function MySuperModule(...) { 
    ... 
    } 

    MySuperModule.prototype,fn = function(..., done) { 
     var self = this; 
     ... 
     self.logic(..., function done(...) { 
      ... 
      done(...) 
     }); 
    } 

现在MyModule.logic()永远不会被用户显式调用,它只是调用MySuperModule.fn()。 对于所有其他的MyModule函数也是如此,这些函数根据传递给委托链的给定参数有条件地调用。

我的问题如下:

  • 我需要有涵盖所有可能出现的情况
  • 我知道我需要测试功能的不同参数分别测试所有MyModule的功能或只是测试MySuperModule.fn() (如果我做我以前的问题是错误的,因为我根本不会真的测试MyModule函数),我将如何使用MySuperModule.fn(),因为它的done()回调是调用依赖于调用MyModule.logic()done()回调的参数,这又取决于提供给MySuperModule.fn()参数的参数。

回答

1

在我看来,你应该测试单个函数,而不管它们是否被用户直接调用。

单元测试的目的是试图确保测试的各个单元完成他们所期望的任务。如果您(相对)确信您的个人职能/单位表现得如预期一样,那么您可以更有信心地相互配合。

很难从代码中真正收集到模块的性质,因此建议如何实施测试很困难。但是,您所要求的是如何验证您的done/callback函数是否被调用以及使用哪个参数。为此我建议使用存根。我通常使用sinon,但我相信其他类似的工具可用。

var sinon = require("sinon"); 
    var should = require("chai").should(); 
    var yourModule = require("your-module"); 

    var doneStub = sinon.stub(); 
    yourModule.yourFunction(..., doneStub); 
    doneStub.should.have.been.called; 
    var args = doneStub.getCall(0).args; 
    args[ 0 ].should.be.eql(...); 
    // etc etc 

您还应该考虑使用测试跑步者,我喜欢mocha

0

您应该进行渐进式测试。你应该测试每个功能。 这里你如何继续。

  1. 为父函数编写测试用例。嘲笑它调用的内部函数。您可以使用sinon库进行嘲弄。
  2. 对于第二个问题,您可以使用sinon mock的yield函数来模拟任何回调函数,并且您还可以指定该回调所需的输出。通过这种方式,您可以使用不同的方案测试您的多个自定义输出的功能。
1

这真的取决于你如何在MySuperModule上注入MyModule。但首先我会指出,在单元测试中,您必须单独测试MyModule,使用MyModule中的Mocked版本和所有其他依赖项来测试MySuperModule。这是因为你不想测试MyModule两次,不需要这个。

所以创建存根有一个名为Sinon.JS的库,它工作得很好。

因此,如果出于任何原因,您只是想让MyModule间谍,这意味着您只需将侦听器附加到MyModule(它应用于MyModule方法),该侦听器会计数并告知是否曾经调用过某个给定的方法, 。

var MyModuleMethodASpy = sinon.spy(MyModulem 'MethodA'); 
MySuperModule.someMethod(); 
assert(MyModuleMethodASpy.called) 

所以这个代码创建了一个间谍,引发对MySuperModule和检查一些方法,如果MyModule.MethodA()是不断调用。

您可以创建存根,以及如果你想控制哪些依赖于具体的方法,例如回报:

var MyModuleStub = sinon.stub(MyModule, 'MethodA').returns([...somedata]); 
相关问题