2014-09-26 135 views
0

有可能是太多这类问题就在这里,但没有我发现想出一个好的解决方案。 在我看来,问题应该太常见了。 脏伪代码: Acontroller角茉莉花(1.3)控制器模拟服务测试

app.controller('Acontroller',function($scope,$q, Aservice){ 

    $scope.someScopeVariable = null; 

    function refresh(){ 
    $q.all([ 
    Aservice.getCollectionA().then(function(results){ 
     return $scope.collectionA = results}), 
    Aservice.getCollectionB().then(function(results){ 
     return $scope.collectionB = results}) 
    ]); 
    }; 

    $scope.someScopeFunction = function(){ 
     Aservice.someServerUpdateCall().then(function(){ 
     refresh().then(function(){ 
      $scope.someScopeVariable = 'woot' 
     } 
     } 
    } 
}) 

这真的只是写不好真的?我正在秃头上剔除剩余的头发,试图测试someScopeFunction。

你怎么测试呢? (茉莉(只佬1.3))

我可以测试承诺的第一梯队,但我不能简单地断言刷新函数被调用。我可以嘲笑这项服务,但是我有一段时间让这个刷新功能被窥探。我会假设我必须实例化控制器(找到类似的解决方案),尽管这似乎有点疯狂。

所以(原谅的CoffeeScript):

describe 'Acontroller', -> 
    mockService = {} 
    aResponseObject = 
    a:1 
    b:2 
    beforeEach -> module('app') 

    beforeEach inject ($controller,$q, $rootScope) -> 

    emptyPromise = -> 
     defer = $q.defer 
     defer.resolve() 
     defer.promise 


    responsePromise = -> 
     defer = $q.defer() 
     defer.resolve([aResponseObject],[aResponseObject]) 
     defer.promise 

    mockService.getCollectionA = jasmine.createSpy('getCollectionA').andReturn responsePromise() 
    mockService.getCollectionB = jasmine.createSpy('getCollectionB').andReturn responsePromise() 
    mockService.someServerUpdateCall = jasmine.createSpy('someServerUpdateCall').andReturn emptyPromise() 
    scope = $rootScope.$new() 
    $controller 'Acontroller', 
     $scope: scope 
     Aservice: mockService 

    $rootScope.$apply ## resolve promises 

    describe 'someScopeFunction', -> 

    it 'should call Aservice with someServerUpdateCall', -> 

     scope.someScopeFunction() 
     scope.$digest 
     expect(Aservice.someSererUpdateCall).toHaveBeenCalled() ##this should work 

这种期望工作正常,虽然确认了下一次调用刷新就是我不知所措。看到它与范围无关,我会假设我必须实例化控制器?

我已与其他战略,包括像玩耍了:

done = false 
refresh = jasmine.createSpy('refresh') 

scope.someScopeFunction().then() -> done = true 

waitsFor -> done 

runs -> 
    scope.$apply -> 
    expect(refresh).toHaveBeenCalled() 

无济于事虽然承诺没有得到解决。

听说摩卡使异步调用多一点简单的,但我真的很害怕尝试重新开始。

+1

哪里是你的测试? – PSL 2014-09-26 23:51:45

回答

0

所以,我想我想通了。 我改变了作用域上的原始函数来代替注入refresh()函数。 然后在针对返回承诺的测试中注入间谍后,在范围上调用$摘要。

$scope.someScopeFunction = (refreshFn=refresh) 
    Aservice.someServerUpdateCall().then -> 
    refreshFn().then -> 
     $scope.someScopeVariable = 'woot' 

测试将被:

describe 'Acontroller', -> 

    mockService = {} 
    mocks = {} 
    aResponseObject = 
    a:1 
    b:2 
    beforeEach -> module('app') 

    beforeEach inject ($controller,$q, $rootScope) -> 

    mocks.emptyPromise = -> 
     defer = $q.defer 
     defer.resolve() 
     defer.promise 


    mocks.responsePromise = -> 
     defer = $q.defer() 
     defer.resolve([aResponseObject],[aResponseObject]) 
     defer.promise 

    mockService.getCollectionA = jasmine.createSpy('getCollectionA').andReturn mocks.responsePromise() 
    mockService.getCollectionB = jasmine.createSpy('getCollectionB').andReturn mocks.responsePromise() 
    mockService.someServerUpdateCall = jasmine.createSpy('someServerUpdateCall').andReturn mocks.emptyPromise() 

    scope = $rootScope.$new() 

    $controller 'Acontroller', 
     $scope: scope 
     Aservice: mockService 

    $rootScope.$apply ## resolve promises 

    describe 'someScopeFunction', -> 

    it 'should call refresh() after someServerUpdateCall', -> 
     refresh = jasmine.createSpy('refresh').andReturn(mocks.emptyPromise()) 
     scope.someScopeFunction(refresh) 
     scope.$digest -> 
     expect(refresh).toHaveBeenCalled()