如何在'then'中存根角度转换承诺并验证操作

时间:2015-01-19 14:27:08

标签: angularjs promise sinon angular-translate

我正在使用angular-translate翻译应用程序,但无法修复我的测试套件。

之前 - 控制器看起来像:

$scope.$on 'new-fetch-controller:step-2', ->
  if EmailUtils.validate(self.contributorEmail)
    ToastService.show "Did you forget to add #{self.contributorEmail}?", 3
    self.addEmail(self.contributorEmail

之前 - 测试看起来像:

    beforeEach inject ($injector) ->
      mockService = $injector.get 'ToastService'

    it 'calls toast service on adding email', ->
      showSpy = @sinon.spy(mockService, 'show')        

      basics.contributorEmail = "test@test.com"
      newFetchScope.nextStep()

      expect(showSpy).to.have.been.calledWith("Did you forget to add test@test.com?", 3)

之后,控制器看起来像(注意ToastService的调用现在在承诺中):

 $scope.$on 'new-fetch-controller:step-2', =>
  if EmailUtils.validate(@contributorEmail)
    $translate('fetches.new.contributors.auto_added', {email: @contributorEmail}).then (translation) ->
      ToastService.show translation, 3

    @addEmail(@contributorEmail)

现在测试失败了:

Failure/Error: expected show to have been called at least once, but it was never called

如何修复测试?

1 个答案:

答案 0 :(得分:0)

我设法解决了这样的测试:

  1. 我将$ translate服务分配给控制器中的变量,以便稍后用假服务替换它:

    @translate = $ translate

  2. 然后我用假翻译服务替换它,它返回一个已解决的promise和调用范围。$ apply()在期待任何结果之前(注意:'basics'是我的控制器 - 作为范围别名):

    it 'calls toast service on adding email', ->
      basics.translate = (key) ->
        deferred = $q.defer()
        deferred.resolve('some translation')
    
      deferred.promise
    
      showSpy = @sinon.spy(mockService, 'show')
    
      basics.contributorEmail = "test@test.com"
      newFetchScope.nextStep()
      newFetchScope.$apply()
    
      expect(showSpy).to.have.been.calledWith('some translation', 3)
    
  3. 如果有人有替代解决方案或一般建议 - 请发表您的想法。