2016-12-17 208 views
0

我在我的控制器以下功能:

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是$资源。这种方法是通过下面的代码片段测试:

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。有谁知道为什么会发生这种情况,以及我如何解决这个问题?

回答

1

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

不知道什么间谍的q功能呢,但我会在本例中使用Angular's $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); 
}); 

注意,测试时承诺(至少与$q服务),承诺的分辨率是联系在一起的消化周期,这意味着then函数只有在摘要运行后才会调用。

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

+0

我在某个时候尝试了这一点 - 但没有继续这个,因为它给了我另一个异常,'错误:意外的请求:GET http:// localhost/api/endpoint。没有更多的预期要求。在控制器的init方法中有一个不同的API调用,它必须由$ rootScope。$ apply调用(它也出现在$ rootScope。$ digest中)。我试图监视其他端点,但没有解决错误。 – cscan

+0

您需要通过'$ httpBackend'预期请求。请参阅https://docs.angularjs.org/api/ngMock/service/$httpBackend – tasseKATT