我正在尝试编写一个单元测试,以验证是否调用了$rootScope.$broadcast('myApiPlay', { action : 'play' });
。
这是myapi.js
angular.module('myApp').factory('MyApi', function ($rootScope) {
var api = {};
api.play = function() {
$rootScope.$broadcast('myApiPlay', { action : 'play' });
}
return api;
});
这是我的单元测试:
describe('Service: MyApi', function () {
// load the service's module
beforeEach(module('myApp'));
// instantiate service
var MyApi;
var rootScope;
beforeEach(function () {
inject(function ($rootScope, _MyApi_) {
MyApi = _MyApi_;
rootScope = $rootScope.$new();
})
});
it('should broadcast to play', function () {
spyOn(rootScope, '$broadcast').andCallThrough();
rootScope.$on('myApiPlay', function (event, data) {
expect(data.action).toBe('play');
});
MyApi.play();
expect(rootScope.$broadcast).toHaveBeenCalledWith('myApiPlay');
});
});
这是我在运行grunt test
:时遇到的错误
PhantomJS 1.9.7 (Windows 7) Service: MyApi should broadcast to pause FAILED
Expected spy $broadcast to have been called with [ 'myApiPlay' ] but it was never called.
我也尝试过使用expect(rootScope.$broadcast).toHaveBeenCalled()
,但我遇到了类似的错误:Expected spy $broadcast to have been called.
。
我想验证该方法是否已使用正确的参数进行了调用。
谢谢!
测试未通过的原因是您正在监视错误的$broadcast函数。在beforeEach设置中,您要求注入$rootScope,然后通过调用$rootScope创建一个子作用域$new()。
$rootScope的返回值$new()不再是rootScope,而是根作用域的子作用域。
beforeEach(function () {
//inject $rootScope
inject(function ($rootScope, _MyApi_) {
MyApi = _MyApi_;
//create a new child scope and call it root scope
rootScope = $rootScope.$new();
//instead don't create a child scope and keep a reference to the actual rootScope
rootScope = $rootScope;
})
});
在您的play函数中,您在$rootScope上调用$broadcast,但在您的测试中,您正在监视$rootScope的子级。
$rootScope.$broadcast('myApiPlay', { action : 'play' });
因此,要结束它,请删除对$rootScope的调用$new(),只需监视注入器给您的$rootScope。提供给单元测试的$rootScope与提供给API服务的$rootScope相同,因此您应该直接监视$rootScope。
看看plunkrhttp://plnkr.co/edit/wN0m8no2FlKf3BZKjC4k?p=preview
这将对您有所帮助https://stackoverflow.com/a/17227264/2594499你的测试不清楚。避免在条件、回调和类似的事情中使用"expect"。若你们的条件不成立,那个么你们的测试并没有断言。
最好使用函数的第二个参数:
.toHaveBeenCalledwith('someEvent', someObj);