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

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

问题描述

我想对 node.js 模块中的一些函数进行单元测试.我认为模拟第三个模块会有所帮助.特别是为了避免撞到数据库

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 函数,但我不希望测试点击数据库.我可能还没有实现 account 模块.

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.

茉莉花规格# 规格/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/Syringe, 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
}

因此,您可以从 mocha 测试中创建一个虚拟帐户对象,并在实际测试中使用 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();

    });

});

很抱歉没有把它写在咖啡稿里,但我不习惯.

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

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

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