繁体   English   中英

Angular.js承诺在使用业力进行单元测试服务时无法解决

[英]Angular.js promise not resolving when unit testing service with karma

我正在尝试对Angular.js服务进行单元测试,并且需要对从Mock服务返回的promise(使用Jasmine)设置一个期望值。 我正在使用业力单元测试框架。 相关的代码段如下:

// I can't figure out how to do the equivalent of a $scope.$digest here. 
var loginStatusPromise = FacebookService.getFacebookToken();
loginStatusPromise.then(function(token) {
    expect(false).toBeTruthy(); // If this test passes, there is something going wrong!
    expect(token).not.toBeNull(); // The token should be ValidToken
    expect(token).toBe('ValidToken');
});

完整的单元测试代码可以在这里看到。

问题是promise.then语句在执行业力时永远不会触发。 因此,我的期望陈述都没有被执行。 在我的控制器测试中,我使用$ scope。$ digest()来解决承诺,但我不清楚在服务测试中如何做到这一点。 我认为在服务测试中没有“范围”的概念。

我在这里有错误的结尾吗? 我是否需要将$ rootScope注入我的服务测试,然后使用$ digest? 或者,还有另一种方式吗?

我遇到了这个问题并通过简单地在测试结束时添加$rootScope.$apply()解决它

根据@mpm的建议,您的FacebookService可能是个问题。 你确定它没有在Facebook依赖关系中发生任何http调用,这在单元测试期间不会发生吗? 你确定已经延迟调用了resolve吗?

假设您正在使用ngFacebook / ngModule快速说明解决方案/想法之前该项目没有单元测试! 您确定要使用此项目吗?

我在Github上快速扫描了你的单元测试,发现以下缺失: -

1)模块初始化 ngFacebook需要或者你需要初始化你做同样事情的模块。

beforeEach(module('ngFacebook'));

要么

beforeEach(module('yieldtome'));

2)认真考虑模拟ngFacebook模块

在单元级别测试中,您将在模拟气泡中测试代码,其中外部接口被删除。

否则)尝试添加调用API,如下所示: -

 $rootScope.$apply(function() {
     this.FacebookService.getFacebookToken().then(function(){
        //your expect code here
     });
    });
 $httpBackend.flush();//mock any anticipated outgoing requests as per [$httpBackend][2]
beforeEach(function(){
   var self=this;
    inject(function($rootScope,Facebook){
        self.$rootScope=$rootScope;
        self.Facebook=Facebook;
    });
})

it('resolves unless sourcecode broken',function(done){
    // I can't figure out how to do the equivalent of a $scope.$digest here. 
    var loginStatusPromise = this.FacebookService.getFacebookToken();
    loginStatusPromise.then(function(token) {
        expect(token).toBe('ValidToken');
        done();
    });
    $rootscope.$apply();

});

https://docs.angularjs.org/api/ng/service/$q

我同意上述答案,即服务应该与$rootScope无关。

在我的情况下有一个$q承诺,它使用了第二个服务在内部解决了一个承诺。 无法解决外部问题,除非我将$rootScope.$digest()到我的服务代码中(不是测试)...

我最终编写了这个快速的垫片,以便在我的测试中使用$q ,但要小心,因为它只是一个例子,而不是一个完整的$q实现。

beforeEach(module(function($provide) {
  $provide.value('$q', {
    defer: function() {
      var _resolve, _reject;
      return {
        promise: {
          then: function (resolve, reject) {
            _resolve = resolve;
            _reject = reject;
          }
        },
        resolve: function (data) {
          window.setTimeout(_resolve, 0, data);
        },
        reject: function (data) {
          window.setTimeout(_reject, 0, data);
        }
      };
    }
  });
}));

希望它对某人有用,或者如果您有任何反馈。

谢谢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM