iva*_*rni 36 jasmine angularjs jasmine2.0
我知道在摘要周期中调用$digest
或$apply
手动会导致"$ digest已在进行中"错误,但我不知道为什么我在这里得到它.
这是一个包装服务的单元测试$http
,服务很简单,只是防止对服务器进行重复调用,同时确保尝试执行调用的代码仍然获得预期的数据.
angular.module('services')
.factory('httpService', ['$http', function($http) {
var pendingCalls = {};
var createKey = function(url, data, method) {
return method + url + JSON.stringify(data);
};
var send = function(url, data, method) {
var key = createKey(url, data, method);
if (pendingCalls[key]) {
return pendingCalls[key];
}
var promise = $http({
method: method,
url: url,
data: data
});
pendingCalls[key] = promise;
promise.then(function() {
delete pendingCalls[key];
});
return promise;
};
return {
post: function(url, data) {
return send(url, data, 'POST');
},
get: function(url, data) {
return send(url, data, 'GET');
},
_delete: function(url, data) {
return send(url, data, 'DELETE');
}
};
}]);
Run Code Online (Sandbox Code Playgroud)
单元测试也非常简单,它用于$httpBackend
期望请求.
it('does GET requests', function(done) {
$httpBackend.expectGET('/some/random/url').respond('The response');
service.get('/some/random/url').then(function(result) {
expect(result.data).toEqual('The response');
done();
});
$httpBackend.flush();
});
Run Code Online (Sandbox Code Playgroud)
done()
随着"已经在进行中的$ digest"错误的调用,这会爆发.我不知道为什么.我可以通过包装这样done()
的超时来解决这个问题
setTimeout(function() { done() }, 1);
Run Code Online (Sandbox Code Playgroud)
这意味着done()
在$ digest完成后会排队并运行,但是这解决了我想知道的问题
done()
触发此错误?我有完全相同的测试运行绿色与Jasmine 1.3,这只发生在我升级到Jasmine 2.0并重写测试以使用新的异步语法.
dei*_*tch 74
$httpBacked.flush()
实际上开始并完成一个$digest()
循环.昨天我花了整整一天的时间挖掘ngResource和angular-mocks的源代码来深入了解它,但仍然没有完全理解它.
据我所知,目的$httpBackend.flush()
是完全避免上面的异步结构.换句话说,语法it('should do something',function(done){});
和$httpBackend.flush()
不能很好地一起玩.非常的目的的.flush()
是通过未决异步回调推,然后返回.它就像done
围绕所有异步回调的一个大包装器.
因此,如果我理解正确(现在它对我有用),正确的方法是done()
在使用时删除处理器$httpBackend.flush()
:
it('does GET requests', function() {
$httpBackend.expectGET('/some/random/url').respond('The response');
service.get('/some/random/url').then(function(result) {
expect(result.data).toEqual('The response');
});
$httpBackend.flush();
});
Run Code Online (Sandbox Code Playgroud)
如果添加console.log语句,您会发现在flush()
循环期间始终发生所有回调:
it('does GET requests', function() {
$httpBackend.expectGET('/some/random/url').respond('The response');
console.log("pre-get");
service.get('/some/random/url').then(function(result) {
console.log("async callback begin");
expect(result.data).toEqual('The response');
console.log("async callback end");
});
console.log("pre-flush");
$httpBackend.flush();
console.log("post-flush");
});
Run Code Online (Sandbox Code Playgroud)
然后输出将是:
预取
冲洗前
异步回调开始
异步回调结束
后冲水
每次.如果您真的想看到它,请抓住范围并查看scope.$$phase
var scope;
beforeEach(function(){
inject(function($rootScope){
scope = $rootScope;
});
});
it('does GET requests', function() {
$httpBackend.expectGET('/some/random/url').respond('The response');
console.log("pre-get "+scope.$$phase);
service.get('/some/random/url').then(function(result) {
console.log("async callback begin "+scope.$$phase);
expect(result.data).toEqual('The response');
console.log("async callback end "+scope.$$phase);
});
console.log("pre-flush "+scope.$$phase);
$httpBackend.flush();
console.log("post-flush "+scope.$$phase);
});
Run Code Online (Sandbox Code Playgroud)
你会看到输出:
pre-get undefined
预冲洗未定义
异步回调开始$ digest
异步回调结束$ digest
后期未定义
Mat*_*cum 12
@deitch是对的,$httpBacked.flush()
触发摘要.问题是,当$httpBackend.verifyNoOutstandingExpectation();
每个it
完成后运行时,它也有一个摘要.所以这是事件的顺序:
flush()
哪个触发摘要then()
执行done()
执行verifyNoOutstandingExpectation()
运行时触发摘要,但您已经在一个,所以你得到一个错误.done()
仍然很重要,因为我们需要知道其中的'期望' then()
甚至被执行.如果then
没有运行那么你现在可能知道有失败.关键是要确保摘要在完成之前完成done()
.
it('does GET requests', function(done) {
$httpBackend.expectGET('/some/random/url').respond('The response');
service.get('/some/random/url').then(function(result) {
expect(result.data).toEqual('The response');
setTimeout(done, 0); // run the done() after the current $digest is complete.
});
$httpBackend.flush();
});
Run Code Online (Sandbox Code Playgroud)
把done()
在超时将使其立即执行当前的消化完成后().这将确保expects
您想要运行的所有内容都将实际运行.
归档时间: |
|
查看次数: |
10601 次 |
最近记录: |