测试快速路线方法

时间:2015-02-22 00:44:58

标签: node.js unit-testing express mocha chai

我正在尝试检查是否在快速get方法中调用了res.json()。

但是在我的get方法中,它在执行res.json();

之前等待一个promise

这是控制器方法:

function get(req, res, next) {

    Service
        .doImportantThings()
        .then(success, error);

    function success(result) {
        res.json(result); // Method i want to test.
    }

    function error(error) {
        // Handles it
    }
}

服务:

function doImportantThings() {
    var deferred = q.defer();

    doStuff
        .then(success, error);

    function success(results) {
        deferred.resolve(output);
    }

    function error() {
        deferred.reject();
    }

    return deferred.promise;
}

测试:

    beforeEach(function () {
        var Service = require('../../../../app/services/service');
        ServiceMock = sinon.mock(Service);
        methodExpect = ServiceMock.expects('doImportantThings').returns(q.resolve("test"));
        res.json = sinon.spy();

        expressController = require('../../../../app/controllers/v1/controller');
    });

    afterEach(function() {
        ServiceMock.restore();
    });

    describe('get()', function () {

        it('should call res.json() one time', function () {
            expressController.get(req, res);    
            expect(res.json).to.have.been.calledOnce; // Fails 
        });

        it('should call res.json() with object argument.', function () {
            expressController.get(req, res)
            expect(res.json).to.have.been.calledWith("test"); // Fails


        });

    });

因为我正在使用promises,所以期望总是返回false。我试过使用mocha的done()回调没有成功。我还尝试将回调作为控制器参数并从那里调用完成或者在那里进行调用,但是测试要么超时要么不断言。

我找到的所有答案都谈到了使用supertest可能会有效,但我希望能够在不向资源发出http请求的情况下对其进行测试。

1 个答案:

答案 0 :(得分:0)

我刚刚解决了同样的问题,最终决定将我的'get'方法包装在一个promise中,允许我的测试在promise解决后完成。我在路线上打电话给res.send。我已经将我的逻辑从我的路径文件移到一个单独的文件中,看起来你可能也已经完成了。所以,这实际上就是我现在所拥有的:

/routes.js

var routeMethods = require('./methods');

router.get('/get-data/:id', function(req, res) {

    routeMethods.getTheData(req.params.eventId).then(

        (result) => {
            res.status(result.statusCode).send(result.response);
        });
    });
}

/methods.js

var externalTools = require('./externalTools.js');

var routeMethods = {

    getTheData: function (id) {

        return new Promise((resolve, reject) => {

            externalTools.getDataFromExternalService(id)

                .then((externalResponse) => {

                    resolve({'statusCode': externalResponse.statusCode,
                             'response': externalResponse.body});

                }, (errorDetails) => {

                    reject({'statusCode': errorDetails.statusCode,
                            'response': errorDetails.error + ' ' + id});

                });
        });
    }
};

module.exports = routeMethods;

/tests.js

var expect = require('chai').expect,
    request = require('request'),
    should = require('chai').should(),
    sinon = require('sinon'),
    methods = require('./methods');

describe('get data routes', function() {

    describe('getData', function() {

        it('should return the correct statusCode and error summary when theres a whapi error', function (done) {

            sinon
                .stub(request, 'get')
                .yields('404', {'statusCode': 404}, JSON.stringify({"faults": [{"faultCode": "10003","faultString": "Resource not found - test","faultName":""}]}));

            methods.getTheData('1234').then(

                (response) => {},
                (response) => {

                    expect(response.statusCode).to.equal(404);
                    done();
                });

            request.get.restore();

        });

    });

});