【问题标题】:Test angular $q with jasmine用茉莉花测试角度 $q
【发布时间】:2017-05-02 22:53:55
【问题描述】:

我的控制器中有以下功能:

function putActivities () {
    var promises = [];
    view.activities.forEach(function (activity) {
        promises.push(API.putActivities({activity: activity}).$promise);
    });
    $q.all(promises).then(function () {
        view.finished = true;
    });
}

其中 API 是一个 $resource。该方法通过以下sn-p测试:

describe('putActivities', function() {
    beforeEach(function() {
        view.activities = ['hello'];
        spyOn(API, 'putActivities').and.callFake(function () {
            return {
                $promise: q(function () {})
            }
        });
    });
    it('view is finished after putting activities', function() {
        view.putActivities();
        expect(view.finished).toEqual(true);
    });
});

由于某种原因,$q.all 永远不会解析,view.finished 永远不会设置为 true。有谁知道为什么会发生这种情况以及我该如何解决?

【问题讨论】:

    标签: angularjs unit-testing jasmine angular-promise


    【解决方案1】:

    间谍返回的虚假承诺需要手动解决(或拒绝)。

    不确定 spy 中的 q 函数是做什么的,但我将在示例中使用 Angular 的 $q

    beforeEach(function() {
    
      view.activities = ['hello'];
      mockedPromises = [];
    
      spyOn(API, 'putActivities').and.callFake(function() {
    
        var defer = $q.defer();
        mockedPromises.push(defer);
    
        return {
          $promise: defer.promise
        };
      });
    });
    

    现在您可以访问测试中的承诺,并且可以解决或拒绝它们,具体取决于您要测试的场景:

    it('view is finished after putting activities', function() {
    
      view.putActivities();
    
      mockedPromises.forEach(function(promise) {
        promise.resolve();
      });
    
      $rootScope.$apply();
    
      expect(view.finished).toEqual(true);
    });
    

    请注意,在测试 Promise 时(至少使用 $q 服务),Promise 的解析与摘要周期相关联,这意味着只有在摘要运行后才会调用 then 函数。

    测试时,您需要手动触发摘要循环(这样您可以更好地控制流程)。这就是$rootScope.$apply() 所做的。

    【讨论】:

    • 我曾经尝试过这个 - 但没有继续这样做,因为它给了我另一个例外,Error: Unexpected request: GET http://localhost/api/endpoint. No more request expected。在控制器的 init 方法中进行了不同的 API 调用,它必须由 $rootScope.$apply 调用(它也与 $rootScope.$digest 一起发生)。我尝试监视另一个端点,但没有解决错误。
    • 您需要通过$httpBackend 收到请求。见docs.angularjs.org/api/ngMock/service/$httpBackend
    猜你喜欢
    • 2020-08-19
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 2022-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多