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

play 関数では、$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あなた のテストは明確ではありません。条件、コールバックなどで「expect」を使用しないでください。条件が true にならない場合は、アサーションなしでテストできます。

関数の 2 番目のパラメーターを使用することをお勧めします。

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