如何用Jasmine窥探NodeJS模块单例

时间:2016-11-28 03:40:49

标签: node.js unit-testing jasmine

我想使用Jasmine来监视一个直接导出方法的模块:

Mymodule中

module.exports = (arg, arg) => { 
  //do something...
  callAMethod();
  //return
}

茉莉

spyOn(myModule);
// since I don't have any method to use spyOn(myModule, <method>)

我发现我可以使用它:

//describe..
    var myModule = require('./myModule');

       it...
         myModule = jasmine.createSpy().and.callFake(function() {
           return false;
         }); // <-this should work

         functionBeingTested(..args);

         expect(myModule).toHaveBeenCalled(); /*I get false, even if
                                                it is actually called
                                                in the functionBeingTested*/

我发现的另一个解决方案是窥探myModule.prototype或设置jasmine.createSpy().and.returnValue(false),但两者都没有成功。

我如何像上面所说的那样使用spyOn?

1 个答案:

答案 0 :(得分:0)

  • 我创建了一个简单的snippet,它模仿了需要的js 加载库并调用方法的功能。

  • 我列出了三个间谍,每个间谍都有一个不同的场景来解释如何 间谍

注意:

  • 我本身并没有使用require.js,而是模仿了它的功能 然而
  • 因为require.js exports module.exports,我们没有 控制require调用的功能,因此我们可以 无法在该方法上安装间谍。
  • 请按照每个案例进行说明。

希望这有帮助!

    var callAMethod = function() {
      return "Hello";
    }
    var myModule = {};
    myModule.exports = function(name, title) {
     return callAMethod() + " " + title + "." + name;
    }

    // Note that this require mimics the actual require.js require methodology, bascially returns the instantiated version of the library to be used.
    var require = function() {
      return myModule.exports;
    }

    // some function that uses the require library to load the js and then does something with it.
    var testFunc = function() {
      var myMod = require('abc');
      return myMod("Bruce", "Mr");
    }

    describe('test mymodule', function() {
      // This test fails because though you are mocking the instance here and not the actual call.
      it('test that fails', function() {
        var myModuleTest = require('abc');
        myModuleTest = jasmine.createSpy().and.callFake(function() {
          return false;
        });
        var result = testFunc();
        console.log(result);
        expect(result).toBe(false);
      });
      // this test passes since we have hijacked the require attribute itself and then routed its call to return the Boolean true which means that myModule now return the true statement
      it('test that passes', function() {
        require = jasmine.createSpy().and.callFake(function() {
          return function() {
            return true;
          };
        });
        var result = testFunc();
        console.log(result);
        expect(result).toBe(true);
      });

      //callAMethod method call from module.exports may not tested since its the require js that does this call and you have no hook into it, however you can directly test the method like this
      it('test callAMethod', function() {
        console.log(myModule.exports("Bruce", "Mr"));
        spyOn(myModule, 'exports').and.returnValue("Hello Mr.Wayne!");
        var testVal = myModule.exports("Bruce", "Mr");
        expect(testVal).toEqual("Hello Mr.Wayne!");
      })


    });