在测试使用承诺的 Node 模块时,您如何断言
How do you assert when testing a Node module that uses promises?
我有一个节点控制器"simpleController",它依赖于"DataAccess"的实例。控制器在"DataAccess"实例上调用函数"getData",并向其返回一个承诺。如果承诺随后被拒绝,则控制器应返回状态 500。
我想在"simpleController"上写一个测试,但模拟"DataAccess"的实例,这样我就可以返回一个失败的承诺并断言"simpleController"行为符合预期。
我试图编写一个单元测试来执行此操作,但测试超时。
(function (simpleController) {
var DataAccess = require('./DataAccess');
var dataAccessInstance;
simpleController.init = function (dataSource) {
dataAccessInstance = new DataAccess(dataSource);
};
simpleController.setMockDependencies = function (mockDataAccessInstance) {
dataAccessInstance = mockDataAccessInstance;
};
simpleController.performAction = function (req, res) {
var entityId = req.query.id;
dataAccessInstance.getData(entityId)
.then(function (data){
res.status(200).json(data);
},
function (err) {
res.status(200).json(err);
});
}
})(module.exports);
/* global describe, it */
'use strict';
var assert = require('assert');
var sinon = require('sinon');
var Q = require('q');
var DataAccess = require('../lib/temp/DataAccess');
describe('Simple Controller Tests', function () {
var simpleController;
var dataAccess;
beforeEach(function (done) {
simpleController = require('../lib/temp/simpleController');
var dataSource = 'dummy';
dataAccess = new DataAccess(dataSource);
done();
});
it('should return status of 500 if data access fails', function (done) {
// Arrange
var req = { query: { id: '12345678' } };
var res = {};
var deferred = Q.defer();
var stub = sinon.stub(dataAccess, 'getData', function() {
return deferred.promise;
});
simpleController.setMockDependencies(dataAccess);
deferred.promise.fail(function () {
// Assert
assert.ok(stub.called);
assert.equal(res.status, 500);
done();
});
// Act
simpleController.performAction(req, res);
deferred.reject();
});
});
(function () {
function DataAccess(dataSource) {
this.dataSource = dataSource;
}
DataAccess.prototype.getData = function (entityId) {
throw new Error('Not implemented');
};
module.exports = DataAccess;
})();
任何协助将不胜感激。
据我所知,您遇到的问题是您在两个地方为您的承诺提供了失败处理程序。一次是在测试中调用 deferred.promise.fail,一次是通过在控制器中将第二个参数传递给 dataAccessInstance.getData(entityId).then。控制器中的那个可能正在替换您在测试中添加的那个。我建议删除这段代码(它并没有真正做任何有用的事情):
deferred.promise.fail(function () {
// Assert
assert.ok(stub.called);
assert.equal(res.status, 500);
done();
});
而不是在测试中使用空对象作为 res,添加一个状态方法,并在那里做你的断言:
it('should return status of 500 if data access fails', function (done) {
// Arrange
var req = { query: { id: '12345678' } };
var res = {};
var deferred = Q.defer();
var stub = sinon.stub(dataAccess, 'getData', function() {
return deferred.promise;
});
simpleController.setMockDependencies(dataAccess);
res.status = function (status) {
// Assert
assert.ok(stub.called);
assert.equal(status, 500);
done();
};
// Act
simpleController.performAction(req, res);
deferred.reject();
});
另外,请注意,在您的控制器中,您使用 200 表示成功和失败,我认为您打算使用 500 表示失败。最后,你应该在承诺链的末尾添加 .done():
dataAccessInstance.getData(entityId)
.then(function (data){
res.status(200).json(data);
},
function (err) {
res.status(500).json(err);
})
.done();
(见 http://documentup.com/kriskowal/q/#tutorial/the-end)。这将避免在测试失败时超时。
相关文章:
- 当已经使用CasperJS选择了css类元素时,断言该类的存在
- Chai深度包含了对嵌套对象的断言
- Mocha/Chai测试链接到函数返回断言错误
- 断言属性不可配置
- 节点回调参数无法断言instanceof Error
- 如何断言后端端点已被调用
- 断言错误:断言失败:坐标数组的长度应与步幅匹配
- Ractive.DEBUG背后的逻辑缩小了断言
- 未捕获的错误:断言失败:余烬视图需要 1.7 和 2.1 之间的 jQuery
- JavaScript 数组克隆相等断言中的远程行为
- 当“new constructor()”与mocha和chai一起使用时,我如何断言throw
- 断言使用new执行构造函数时抛出错误
- '递归到对象'13076断言在MongoDB中失败
- emberjs追加有效,但引发断言失败错误
- 不可变的Chai断言错误,而预期的结果等于
- 断言var集通过<输入ng模型>不是未定义的
- 断言一个元素是有重点的
- 如何在解析Promise时运行qunit断言
- i18n转换无法使用ember-断言失败:缺少键的转换
- 从生产版本的javascript代码中删除断言