【问题标题】:node js unit testing: mocking require dependencynode js单元测试:模拟需要依赖
【发布时间】:2016-02-19 17:39:57
【问题描述】:

我在为以下设置编写单元测试作为 jira.js 文件(在 node.js 模块中)时遇到问题:

var rest = require('restler'); // https://www.npmjs.com/package/restler

module.exports = function (conf) {
    var exported = {};

    exported.getIssue = function (issueId, done) {
        ...

        rest.get(uri).on('complete', function(data, response) {
        ...
    };

    return exported;
};

现在,我想为我的 getIssue 函数编写单元测试。 “restler”是一个 REST 客户端,我通过它对 JIRA API 进行 REST 调用,以通过我的代码获取 JIRA 问题。

为了能够测试 createIssue(..),我希望能够在 Jasmine 单元测试中模拟“rest”变量。

我如何模拟这个方法?请给我一些指示,以便我可以继续。我曾尝试使用 rewire,但我失败了。

这是我目前所拥有的,但它不起作用(即 getIssue 方法原来是未定义的):

var rewire       = require("rewire");
var EventEmitter = require('events').EventEmitter;
var emitter      = new EventEmitter();
var cfg          = require("../../../config.js").Configuration;
var jiraModule   = rewire("../lib/jira")(cfg);
var sinon        = require("sinon");
var should       = require("should");

// https://github.com/danwrong/restler
var restMock = {
    init : function () {
        console.log('mock initiated'+JSON.stringify(this));

    },
    postJson : function (url, data, options) {
        console.log('[restler] POST url='+url+', data= '+JSON.stringify(data)+
        'options='+JSON.stringify(options));
        emitter.once('name_of_event',function(data){
            console.log('EVent received!'+data);
        });
        emitter.emit('name_of_event', "test");
        emitter.emit('name_of_event');
        emitter.emit('name_of_event');
    }, 
    get : function (url, options) {
        console.log('[restler] GET url='+url+'options='+JSON.stringify(options));
    },
    del : function (url, options) {
        console.log('[restler] DELETE url='+url+'options='+JSON.stringify(options));
    },
    putJson : function (url, data, options) {
        console.log('[restler] PUT url='+url+', data= '+JSON.stringify(data)+
        'options='+JSON.stringify(options));
    }
};

var cfgMock = {
    "test" : "testing"
};

jiraModule.__set__("rest", restMock);
jiraModule.__set__("cfg", cfgMock);

console.log('mod='+JSON.stringify(jiraModule.__get__("rest")));

describe("A suite", function() {
it("contains spec with an expectation", function() {
    restMock.init();
    restMock.postJson(null, null, null);

console.log(cfg.jira);

    // the following method turns out to be undefined but when i console.log out the jiraModule, i see the entire code outputted from that file
    jiraModule.getIssue("SRMAPP-130", function (err, result) {
        console.log('data= '+JSON.stringify(result));
     });

    expect(true).toBe(true);
});
});

如果有人可以指导我如何模拟“其余”需要依赖项和单元测试,这种方法将非常有帮助。

另外,我应该如何模拟传递给 module.exports 的“conf”?

谢谢

【问题讨论】:

    标签: javascript node.js mocking sinon jasmine-node


    【解决方案1】:

    您可以使用proxyquiremockery 来存根/模拟依赖项。

    在下面的示例中,我使用了proxyquire。希望对您有所帮助。


    /* ./src/index.js */
    var rest = require('restler');
    
    module.exports = function (conf) {
      var exported = {};
    
      exported.getIssue = function (issueId, done) {
        var uri = '';
        var reqObj = '';
        var service = {
          auth : ''
        };
    
        rest.postJson(uri, reqObj, service.auth).on('complete', function(data, response) {
          done(data, response);
        });
      };
    
      return exported;
    };
    

    /* ./test/index.js */
    var proxyquire  =  require('proxyquire');
    var assert      =  require('chai').assert;
    var restlerStub = {
      postJson: function() {
        return {
          on: function(event, callback) {
            callback('data', 'response');
          }
        }
      }
    }
    
    var index = proxyquire('../src/index', {'restler': restlerStub})();
    
    describe('index', function() {
      it('should return the desired issue', function(done) {
        var issue = index.getIssue('issueId', function(data, response) {
          assert.equal(data, 'data');
          assert.equal(response, 'response');
          done();
        })
      });
    });
    

    /* ./package.json */
    {
      "scripts": {
        "test": "mocha"
      },
      "dependencies": {
        "restler": "^3.4.0"
      },
      "devDependencies": {
        "chai": "^3.4.1",
        "mocha": "^2.3.4",
        "proxyquire": "^1.7.3"
      }
    }
    

    【讨论】:

    • Jasmine-node 被标记,你为什么使用 mocha?
    • Opps,我没有注意到,但是模拟依赖与测试框架无关。
    • 您好,谢谢指导!!如果我使用proxyquire,我如何传递conf?我还需要模拟 conf ......这是 module.exports 的一个参数......
    • var index = proxyquire('../src/index', {'restler': restlerStub})(conf);
    • 谢谢!这个解释看起来很有希望。在我尝试看看这是否有效之前,还有一件事。我不确定如何触发“完成”事件进行测试(如果您查看其余调用,它会引发一个事件)。上面给出的“restlerSTub”存根在这种情况下是否有效?还是我必须使用 eventemitter 并从我的 restlerStub 函数发出事件?
    猜你喜欢
    • 2015-07-14
    • 2016-02-19
    • 1970-01-01
    • 2023-03-13
    • 2017-09-25
    • 1970-01-01
    • 1970-01-01
    • 2021-02-28
    • 2020-01-05
    相关资源
    最近更新 更多