9

我正在尝试编写一个单元测试来验证它$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..

我想验证该方法实际上是否已使用正确的参数调用。

谢谢!

4

2 回答 2

15

你的测试没有通过的原因是你在监视错误的 $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;
    })
});

在您的播放功能中,您在 $rootScope 上调用 $broadcast,但在您的测试中,您正在监视 $rootScope 的子项。

$rootScope.$broadcast('myApiPlay', { action : 'play' });

所以总结一下,删除对 $rootScope.$new() 的调用,然后只监视注入器给你的 $rootScope。提供给您的单元测试的 $rootScope 与提供给您的 API 服务的 $rootScope 相同,因此您应该直接监视 $rootScope。

查看 plunkr http://plnkr.co/edit/wN0m8no2FlKf3BZKjC4k?p=preview

于 2014-09-12T22:46:06.967 回答
1

这将对您有所帮助https://stackoverflow.com/a/17227264/2594499 您的测试不清楚。避免在条件、回调和类似的事情中使用“期望”。如果您的条件不成立,那么您就可以在没有断言的情况下进行测试。

最好使用函数的第二个参数:

.toHaveBeenCalledwith('someEvent', someObj);
于 2014-09-12T22:24:51.983 回答