AngularJSのpromiseが解決した結果が伝搬するには、$digestループを開始する必要がある
こんにちは。牡蠣のパスタをたべました。きたけーです。
今日、Angularでこんなテストコードを書いたのですが、promiseを解決したときに実行されるコールバックが実行されなくて困りました。
describe 'Controller: UserController', -> beforeEach module 'SomeApp' UserController = {} scope = {} beforeEach inject ($controller, $rootScope, User, $q) -> scope = $rootScope.$new() spyOn(User, 'query').and.callFake -> deferred = $q.defer() deferred.resolve {name: "kitak"} deferred.promise UserController = $controller 'UserController', { $scope: scope } it 'should attach user name to the scope', -> # user.name が undefined でテストが落ちてしまう。 expect(scope.user.name).toBe "kitak"
AngularJS - why is $apply required to properly resolve a $q promise? - Stack Overflow によると、promiseを解決した場合に、結果はすぐに伝搬せずに、$digestループの中で伝搬するとのこと。 このテストコードでは(当然ですが)ブラウザのイベントが発生したりはしないので、$digestループは開始しません。
なので、scope.$apply()
で明示的に$digestループを開始させてあげることでテストが通ります。
it 'should attach user name to the scope', -> scope.$apply() expect(scope.user.name).toBe "kitak"