如何在对 AngularJS 控制器进行单元测试时模拟网络延迟
How can I simulate a network delay when unit testing an AngularJS controller?
我正在使用模块ngMock中的$httpBackend
服务来模拟GET请求。 从 AngularJS 文档中,下面是一个示例控制器:
// The controller code
function MyController($scope, $http) {
var authToken;
$http.get('/auth.py').success(function(data, status, headers) {
authToken = headers('A-Token');
$scope.user = data;
});
$scope.saveMessage = function(message) {
var headers = { 'Authorization': authToken };
$scope.status = 'Saving...';
$http.post('/add-msg.py', message, { headers: headers } ).success(function(response) {
$scope.status = '';
}).error(function() {
$scope.status = 'ERROR!';
});
};
}
并且,这是相应的茉莉花测试规范:
// testing controller
describe('MyController', function() {
var $httpBackend, $rootScope, createController;
beforeEach(inject(function($injector) {
// Set up the mock http service responses
$httpBackend = $injector.get('$httpBackend');
// backend definition common for all tests
$httpBackend.when('GET', '/auth.py').respond({userId: 'userX'}, {'A-Token': 'xxx'});
// Get hold of a scope (i.e. the root scope)
$rootScope = $injector.get('$rootScope');
// The $controller service is used to create instances of controllers
var $controller = $injector.get('$controller');
createController = function() {
return $controller('MyController', {'$scope' : $rootScope });
};
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should fetch authentication token', function() {
$httpBackend.expectGET('/auth.py');
var controller = createController();
$httpBackend.flush();
});
it('should send msg to server', function() {
var controller = createController();
$httpBackend.flush();
// now you don’t care about the authentication, but
// the controller will still send the request and
// $httpBackend will respond without you having to
// specify the expectation and response for this request
$httpBackend.expectPOST('/add-msg.py', 'message content').respond(201, '');
$rootScope.saveMessage('message content');
expect($rootScope.status).toBe('Saving...');
$httpBackend.flush();
expect($rootScope.status).toBe('');
});
it('should send auth header', function() {
var controller = createController();
$httpBackend.flush();
$httpBackend.expectPOST('/add-msg.py', undefined, function(headers) {
// check if the header was send, if it wasn't the expectation won't
// match the request and the test will fail
return headers['Authorization'] == 'xxx';
}).respond(201, '');
$rootScope.saveMessage('whatever');
$httpBackend.flush();
});
});
如上所述,模拟请求在执行测试时会立即响应。 我想在模拟 GET 请求上设置延迟。 这可能吗? 我有一种感觉,需要$timeout
服务来实现这一目标。
奖励问题:设置这样的延迟有什么缺点吗? 这在 AngularJS 单元测试中是合理的做法吗?
为$httpBackend创建一个装饰器,如下所示: http://endlessindirection.wordpress.com/2013/05/18/angularjs-delay-response-from-httpbackend/
将其放入您的应用中.js,在每个模拟或直通响应期间延迟 700 毫秒:
.config(function($provide) {
$provide.decorator('$httpBackend', function($delegate) {
var proxy = function(method, url, data, callback, headers) {
var interceptor = function() {
var _this = this,
_arguments = arguments;
setTimeout(function() {
callback.apply(_this, _arguments);
}, 700);
};
return $delegate.call(this, method, url, data, interceptor, headers);
};
for(var key in $delegate) {
proxy[key] = $delegate[key];
}
return proxy;
});
})
额外答案:我相信时间不是你会在单元测试中测试的东西。但可以肯定的是,您需要测试服务器错误,这就是模拟http派上用场的原因。
我在原型设计时使用这样的延迟,这也是一个有效的场景。
相关文章:
- 如何在ember单元测试中模拟_super()方法
- 单元测试:使用酶模拟父组件中子组件的点击事件
- 如何模拟json数据进行单元测试
- 如何用mocha和rewire模拟node.js单元测试中的Q方法
- 单元测试中的模拟模型
- 用于单元测试的模拟Angular引导程序ui指令
- Angular js单元测试模拟文档
- 在茉莉花单元测试中模拟鼠标悬停
- 单元测试的模拟文件输入
- Aurelia单元测试-如何模拟自定义解析器
- 在单元测试时模拟 ES6 依赖项
- 茉莉花单元测试模拟一个承诺
- 如何模拟快乐.js回复 Sinon 进行单元测试
- 如何在对 AngularJS 控制器进行单元测试时模拟网络延迟
- 将模拟提供程序注入到角度单元测试中
- 在茉莉花单元测试中仅模拟今天的日期
- AngularJs 单元测试 - 模拟承诺不执行“然后”
- 如何在angular的单元测试中模拟警报
- 单元测试——方法中的模拟方法
- AngularJS 中的单元测试 - 模拟服务和承诺