揭示模块模式 - 使用Jasmine进行单元测试

bac*_*esk 9 javascript jasmine

在与揭示模块模式的短暂浪漫之后,我开始意识到单元测试模块的挫折.然而,我无法决定是否是我测试模块的方法或是否存在某种形式的解决方法.

请考虑以下代码:

var myWonderfulModule = (function () {
  function publicMethodA (condition) {
    if(condition === 'b') {
      publicMethodB();
    }
  }

  function publicMethodB () {
    // ...
  }

  return {
    methodA : publicMethodA,
    methodB : publicMethodB
  }
}());
Run Code Online (Sandbox Code Playgroud)

如果我想测试(使用Jasmine)通过publicMethodA到publicMethodB的各种路径.我可能会写一个小测试:

it("should make a call to publicMethodB when condition is 'b'", function() {
  spyOn(myWonderfulModule , 'publicMethodB');
  myWonderfulModule.publicMethodA('b');
  expect(myWonderfulModule.publicMethodB).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)

如果我理解正确,那么闭包中的publicMethodB副本无法更改.即使我之后更改myWonderfulModule.publicMethodB:

myWonderfulModule.publicMethodB = undefined;
Run Code Online (Sandbox Code Playgroud)

调用myWonderfulModule.publicMethodA仍然会运行B的原始版本.

上面的例子当然是简化的,但是我可以想到很多场景可以通过方法对条件路径进行单元测试.

这是暴露模块模式的限制还是仅仅是对单元测试的误用?如果没有,我可以使用哪些解决方法?我正在考虑转向RequireJS或恢复非模块化代码.

任何建议赞赏!

And*_*rle 9

你不能测试一个闭包的实习方法.你也不应该窥探它.把你的模块想象成一个黑盒子.你把东西放进去,你得到了一些东西.您应该测试的是,您从模块中获得的东西是您期望的那个.

对模块中的方法进行间谍活动没有多大意义.想一想.你监视它,测试通过.现在你改变了功能,所以它创建了一个bug,测试仍然通过,因为仍然调用了该函数,但你从未提到过这个bug.如果您只是测试出现的东西,您不需要监视内部方法因为,当模块的结果符合您的预期时,它们被称为隐含的.

所以在你的情况下,没有东西进入,没有任何东西出来.这没什么意义,但我相信你的模块与DOM交互或进行ajax调用.这是你可以测试的东西(DOM),或者你应该监视(ajax).

您还应该让自己熟悉控制和依赖注入的反转.这些模式将使您的模块更容易测试.