javascript Jasmine + AngularJS:如何测试使用参数调用的 $rootScope.$broadcast?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25817534/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 05:04:34  来源:igfitidea点击:

Jasmine + AngularJS: How to test $rootScope.$broadcast being called with arguments?

javascriptangularjsjasminekarma-jasmineyeoman-generator-angular

提问by Andrea

I am trying to write a unit test that verifies that $rootScope.$broadcast('myApiPlay', { action : 'play' });is called.

我正在尝试编写一个单元测试来验证$rootScope.$broadcast('myApiPlay', { action : 'play' });所调用的内容。

Here is the myapi.js

这是 myapi.js

angular.module('myApp').factory('MyApi', function ($rootScope) {
    var api = {};
    api.play = function() {
        $rootScope.$broadcast('myApiPlay', { action : 'play' });
    }
    return api;
});

And here is my Unit Test:

这是我的单元测试:

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');
    });
});

Here is the error i'm getting while running grunt test:

这是我在运行时遇到的错误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.

I have also tried with expect(rootScope.$broadcast).toHaveBeenCalled()and I am having a similar error: Expected spy $broadcast to have been called..

我也尝试过expect(rootScope.$broadcast).toHaveBeenCalled(),但遇到了类似的错误:Expected spy $broadcast to have been called..

I would like to verify that that method has actually been called with the right parameters.

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

Thank you!

谢谢!

回答by jcruz

The reason your tests are not passing is because you are spying on the wrong $broadcast function. In your beforeEach setup, you ask to have the $rootScope injected and then you create a child scope by calling $rootScope.$new().

您的测试未通过的原因是您监视了错误的 $broadcast 函数。在您的 beforeEach 设置中,您要求注入 $rootScope,然后通过调用 $rootScope.$new() 创建一个子作用域。

The return value from $rootScope.$new() is no longer the rootScope but a child of the root scope.

$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;
    })
});

In your play function, you are calling $broadcast on the $rootScope but in your test you are spying on a child of $rootScope.

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

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

So to wrap it up, remove the call to $rootScope.$new() and just spy on the $rootScope the injector has given you. The $rootScope provided to your unit test is the same $rootScope provided to your API service so you should be spying directly on the $rootScope.

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

Check out the plunkr http://plnkr.co/edit/wN0m8no2FlKf3BZKjC4k?p=preview

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

回答by ?ukasz

It will be helpful for you https://stackoverflow.com/a/17227264/2594499Your test isn't clear. Avoid using "expect" in conditions, callbacks and things like this. If your condition won't be true, you've got test without assertion.

这对您有帮助https://stackoverflow.com/a/17227264/2594499您的测试不清楚。避免在条件、回调和诸如此类的事情中使用“expect”。如果你的条件不成立,你就得到了没有断言的测试。

It'll be better to use second parameter of function:

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

.toHaveBeenCalledwith('someEvent', someObj);