Unit testing 如何在sails.js中使用Mocha+;西农?

Unit testing 如何在sails.js中使用Mocha+;西农?,unit-testing,sails.js,mocha.js,sinon,Unit Testing,Sails.js,Mocha.js,Sinon,我不熟悉测试,并试图了解如何测试一个相当简单的控制器动作。我遇到的问题是不知道如何完成模拟控制器内部的方法,甚至不知道何时这样做是合适的 该操作在my webapp的数据库中创建一个挂起的用户,并返回一个连接链接。看起来是这样的: module.exports = { create: function(req, res, next) { var name, invitee = req.allParams(); if ( _.i

我不熟悉测试,并试图了解如何测试一个相当简单的控制器动作。我遇到的问题是不知道如何完成模拟控制器内部的方法,甚至不知道何时这样做是合适的

该操作在my webapp的数据库中创建一个挂起的用户,并返回一个连接链接。看起来是这样的:

module.exports = {

    create: function(req, res, next) {

        var name,
            invitee = req.allParams();

        if ( _.isEmpty(invitee) || invitee.name === undefined) {
            return res.badRequest('Invalid parameters provided when trying to create a new pending user.');
        }

        // Parse the name into its parts.
        name = invitee.name.split(' ');
        delete invitee.name;
        invitee.firstName = name[0];
        invitee.lastName = name[1];

        // Create the pending user and send response.
        PendingUser.create(invitee, function(err, pending) {
            var link;

            if (err && err.code === 'E_VALIDATION') {
                req.session.flash = { 'err': err };
                return res.status(400).send({'err':err});
            }

            // Generate token & link
            link = 'http://' + req.headers.host + '/join/' + pending.id;

            // Respond with link.
            res.json({'joinLink': link});
       });

    }

}
'use strict';
/**
 * Tests for PendingUserController
 */

var PendingUserController = require('../../api/controllers/PendingUserController.js'),
        sinon = require('sinon'),
        assert = require('assert');

describe('Pending User Tests', function(done) {

    describe('Call the create action with empty user data', function() {
        it('should return 400', function(done) {

            // Mock the req object.
            var xhr = sinon.useFakeXMLHttpRequest();
            xhr.allParams = function() {
                return this.params;
            };
            xhr.badRequest
            xhr.params = generatePendingUser(false, false, false, false);

            var cb = sinon.spy();

            PendingUserController.create(xhr, {
              'cb': cb
            });
            assert.ok(cb.called);
        });
    });
}

function generatePendingUser(hasName, hasEmail, hasAffiliation, hasTitle) {
    var pendingUser = {};

    if (hasName) pendingUser.name = 'Bobbie Brown';
    if (hasEmail) pendingUser.emailAddress = 'bobbie.brown@example.edu';
    if (hasAffiliation) pendingUser.affiliation = 'Very Exclusive University';
    if (hasTitle) pendingUser.title = "Assistant Professor";

    return pendingUser;
}
我为此方法编写的测试如下所示:

module.exports = {

    create: function(req, res, next) {

        var name,
            invitee = req.allParams();

        if ( _.isEmpty(invitee) || invitee.name === undefined) {
            return res.badRequest('Invalid parameters provided when trying to create a new pending user.');
        }

        // Parse the name into its parts.
        name = invitee.name.split(' ');
        delete invitee.name;
        invitee.firstName = name[0];
        invitee.lastName = name[1];

        // Create the pending user and send response.
        PendingUser.create(invitee, function(err, pending) {
            var link;

            if (err && err.code === 'E_VALIDATION') {
                req.session.flash = { 'err': err };
                return res.status(400).send({'err':err});
            }

            // Generate token & link
            link = 'http://' + req.headers.host + '/join/' + pending.id;

            // Respond with link.
            res.json({'joinLink': link});
       });

    }

}
'use strict';
/**
 * Tests for PendingUserController
 */

var PendingUserController = require('../../api/controllers/PendingUserController.js'),
        sinon = require('sinon'),
        assert = require('assert');

describe('Pending User Tests', function(done) {

    describe('Call the create action with empty user data', function() {
        it('should return 400', function(done) {

            // Mock the req object.
            var xhr = sinon.useFakeXMLHttpRequest();
            xhr.allParams = function() {
                return this.params;
            };
            xhr.badRequest
            xhr.params = generatePendingUser(false, false, false, false);

            var cb = sinon.spy();

            PendingUserController.create(xhr, {
              'cb': cb
            });
            assert.ok(cb.called);
        });
    });
}

function generatePendingUser(hasName, hasEmail, hasAffiliation, hasTitle) {
    var pendingUser = {};

    if (hasName) pendingUser.name = 'Bobbie Brown';
    if (hasEmail) pendingUser.emailAddress = 'bobbie.brown@example.edu';
    if (hasAffiliation) pendingUser.affiliation = 'Very Exclusive University';
    if (hasTitle) pendingUser.title = "Assistant Professor";

    return pendingUser;
}
由于遇到了障碍,我的考试还没有完成。从测试中可以看到,我试图模拟请求对象以及控制器操作
req.allParams()
中调用的第一个方法。但是在控制器中可能调用的第二个方法是
res.badRequest()
,它是一个

这个函数我不知道如何模拟。此外,考虑模拟这个函数还会引发其他各种问题。为什么我首先要模拟这个函数?我认为,单元测试的逻辑是,将代码的一部分与其他部分隔离测试,但这不是有点过分了吗?它还产生了大量额外的工作,因为我需要模拟这个函数的行为,这可能很简单,也可能不容易实现

我在这里写的代码是基于两个概念验证类型的教程(请参见和),但是这些文章没有处理控制器中req和/或res对象的方法的问题


解决方案的正确方法是什么?如有任何见解,将不胜感激

您正在尝试测试挂起的用户控制器上的创建操作,并断言其响应/行为。您可以做的是实际使用发出请求来测试它

我假设您已经使用了Mocha&should.js

 var request = require('supertest');

 describe('PendingUsersController', function() {

  describe('#create()', function() {
     it('should create a pending user', function (done) {
       request(sails.hooks.http.app)
         .post('/pendinguser') 
         //User Data
         .send({ name: 'test', emailAdress: 'test@test.mail', affiliation: 'University of JavaScript', title: 'Software Engineer' })
         .expect(200)
         .end(function (err, res) {
              //true if response contains { message : "Your are pending user."}
              res.body.message.should.be.eql("Your are pending user.");
         });
      });
    });
 });
更多关于控制器测试的信息或查看项目了解更多信息