2

コンストラクタを返すファクトリを作成しました。コンストラクターには、インスタンスのプロパティを監視するウォッチャーが含まれています。そのプロパティがテストで変更されると、ウォッチャーは起動されません。テストの外では、それは解雇されます。$rootScope.$apply は役に立たないようです。

これは、コードとテストの簡略化されたバージョンを含む jsfiddle です。

http://jsfiddle.net/2Ny8x/234/

//--- CODE --------------------------
(function (angular) {
    var myApp = angular.module('myApp', []);

    myApp.factory('MyObject', function($rootScope) {
        function MyObject() {
            this.prop = 5;
            this.watcherCallback = angular.noop;

            $rootScope.$watch(this.prop, this.watcherCallback);
        }

        return MyObject;
    });
})(angular);


// ---SPECS-------------------------
describe('MyObject', function () {
    beforeEach(module('myApp'));

    var MyObject, rootScope;
    beforeEach(inject(function (_MyObject_, $rootScope) {
        MyObject = _MyObject_;
        rootScope = $rootScope;
    }));

    it('calls the watcher when "prop" updates', function() {
        var newObj = new MyObject();
        spyOn(newObj, 'watcherCallback');

        newObj.prop = 10;
        rootScope.$apply();

        expect(newObj.watcherCallback).toHaveBeenCalled();
    });
});

ウォッチャーが起動しないのはなぜですか?

4

1 に答える 1

2
var newObj = new MyObject();

これは に割り当てnoopられnewObj.watcherCallbackます。そして、newObj.watcherCallback(so, noop) ウォッチャー コールバックとして登録します。

spyOn(newObj, 'watcherCallback');

これは別の関数に置き換えnewObj.watcherCallbackられ、この新しいスパイ関数がいつ呼び出されたかを知ることができます。ただし、このスパイ関数を rootScope へのウォッチャー コールバックとして登録しません。レジスタとは元のものです: noop.

そのため、プロパティの値を変更して を呼び出す$apply()と、rootScope はまだnoop関数への参照を保持しており、それを呼び出します。あなたのスパイはそれに気づいていません。

コンストラクターで行うと、正常に機能するはずです。

var that = this;
$rootScope.$watch(this.prop, function() {
    that.watcherCallback();
});
于 2015-02-16T21:22:52.247 に答える