模拟Node.js中的模块进行单元测试 [英] Mocking modules in Node.js for unit testing

查看:151
本文介绍了模拟Node.js中的模块进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在node.js模块中对一些函数进行单元测试。我认为嘲笑第3个模块会有所帮助。特别要避免命中数据库

I want to unit test some functions in a node.js module. I think that mocking a 3rd module would be helpful. In particular to avoid hitting the database

# models/account.coffee
register = (email, password)->
   sha_sum.update(password)
   pw = sha_sum.digest('hex')
   user = 
      email: email
      password: sha_sum.digest('hex')

   users_db.save user, (err, doc)->
      register_callback(err)

account_module = 
   register: register

module.exports = account_module

这是我要测试的模块

# routes/auth.coffee
account = require '../models/account'

exports.auth = 
   post_signup: (req, res)->
      email = req.body.email
      password = req.body.password
      if email and password
          account.register(email, password)
          res.send 200
      else
          res.send 400

我希望能够测试在帖子中使用正确的主体命中此URL会调用 account.register 函数,但我不希望测试命中数据库。我可能还没有实现帐户模块。

I want to be able to test that hitting this url with the correct body in the post calls the account.register function but i don't want the test to hit the database. I may not have implemented the account module yet.

茉莉花规格
#specs / auth.test.coffee
描述'注册', - >

The jasmine spec # specs/auth.test.coffee describe 'signup', ->

   request = require 'request' 
   it 'should signup a user with username and password', (done)->

       spyOn(account, 'register') # this does not work, account.register still called
       url = root + '/signup'
       headers =
           "Content-Type": "application/json" 
       data = 
           email: 'user@email.com'
           password: 'pw'
       body = JSON.stringify(data)
       request {url: url, method: 'POST',json: data, headers: headers }, (err, response, body)->

           expect(response.statusCode).toEqual(200)
           done()

我已经研究过node.js的几个模拟库( https://github.com/easternbloc/注射器 https://github.com/felixge/node-sandboxed-module)但到目前为止还没有成功。无论我在规范中尝试什么, account.register 总是会被执行。整个方法有缺陷吗?

I have looked into several mocking libraries for node.js (https://github.com/easternbloc/Syringe, https://github.com/felixge/node-sandboxed-module) but so far no success. Whatever i try in the spec, the account.register always get executed. Is this whole approach flawed?

推荐答案

我正在使用 mocha 作为测试框架和 sinon 用于模拟,存根和间谍。我建议你将你的帐户模块委托给auth.coffee模块并模仿它:

I am using mocha as the test framework and sinon for mocking, stubing and spying. I would suggest you delegate your account module to the auth.coffee module and mock it like so:

exports.init = function (account) {
    // set account object
}

所以来自摩卡测试你可以创建一个虚拟帐户对象并在实际测试中用sinon模拟它。

so from the mocha test you can then create a dummy account object and mock it with sinon in the actual test.

describe('some tests', function () {

    var account, response, testObject;

    beforeEach(function () {

        account = {
             register: function () { }
        };

        response = {
            send: function () { }
        };

        testObject = require('./auth');
        testObject.init(account);
    });

    it('should test something', function () {

        var req = { body: { email: ..., password: .... } }, // the request to test
            resMock = sinon.mock(response),
            registerStub = sinon.stub(account, 'register');

        // the request expectations
        resMock.expect('send').once().withArgs(200);

        // the stub for the register method to have some process
        registerStub.once().withArgs('someargs');

        testObject.auth(req. response);

        resMock.verify();

    });

});

很抱歉没有把它写在coffescript中,但我不习惯。

Sorry for not writing it down in coffescript but I am not used to it.

这篇关于模拟Node.js中的模块进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆