2016-12-14 62 views
0

我迷路了。我嘗試測試state.go是否在ApiServiceMock在假登錄後解決承諾後調用。
對於這個測試,我得到:
Expected spy go to have been called.AngularJS 1.x組件測試與Karma決心承諾測試成功功能(spyOn)

如果我測試另一項功能,這直接觸發state.go它的工作原理。所以我猜這個承諾並沒有得到解決。

使用Angular組件和測試對我而言是相當新的。如果有人能夠給我提示我做錯了什麼,或者讓我知道整個方法是否是錯誤的,那將是非常棒的。

login.component.ctrl.js

module.exports = function LoginComponentCtrl($state, $log, apiService) { 
    var vm = this; 

    vm.submit = function() { 
     apiService 
     .login(vm.username, vm.password) 
      .then(function(response) { 
      $state.go('storeDetail'); 
      }) 
      .catch(function(errData) { 
      $log.error(errData); 
      }); 
    }; 
    }; 

login.spec.js

var app = require('../../app.js'); 
var login = require('./login.module.js'); 

describe('login', function() { 

    var controller; 
    var element; 
    var scope; 
    var state; 
    var ApiServiceMock; 
    var StateMock; 
    var deferred; 

    beforeEach(angular.mock.module(app)); 
    beforeEach(angular.mock.module(login)); 

    describe('Component: login', function() { 

    beforeEach(inject(function($rootScope, $compile, $componentController, $q){ 
     deferred = $q.defer(); 

     ApiServiceMock = { 
     login: function() { 
      return deferred.promise; 
     } 
     }; 

     StateMock = { 
     go: function() { 
      return true; 
     } 
     }; 

     scope = $rootScope.$new(); 
     controller = $componentController('login', { 
     $scope: scope, 
     apiService: ApiServiceMock, 
     $state: StateMock 
     }); 
     element = angular.element('<login></login>'); 
     element = $compile(element)(scope); 
     scope.$apply(); 
    })); 

    it('on successful login', function() { 
     controller.username = 'Michael Jackson'; 
     controller.password = 'dangerous123'; 

     spyOn(StateMock, 'go').and.callThrough(); 

     controller.submit(); 

     deferred.resolve(); 
     scope.$digest(); 

     expect(StateMock.go).toHaveBeenCalled(); 
    });); 
    }); 
}); 

讓我知道如果我可以添加更多的信息,使之更清楚。

回答

1

直接從您的模擬服務直接返回已解決的承諾。

試試這個

beforeEach(inject(function($rootScope, $compile, $componentController, $q){ 
    ApiServiceMock = { 
    login: function() { 
     return $q.resolve({}); // if angular version is 1.4+ 
    //return $q.when({}); // if angular less than 1.4 
    } 
    }; 

    StateMock = { 
    go: function() { 
     return true; 
    } 
    }; 

    scope = $rootScope.$new(); 
    controller = $componentController('login', { 
    $scope: scope, 
    apiService: ApiServiceMock, 
    $state: StateMock 
    }); 
    element = angular.element('<login></login>'); 
    element = $compile(element)(scope); 
    scope.$apply(); 
})); 

it('on successful login', function() { 
    controller.username = 'Michael Jackson'; 
    controller.password = 'dangerous123'; 

    spyOn(StateMock, 'go').and.callThrough(); 

    controller.submit(); 

    scope.$digest(); 

    expect(StateMock.go).toHaveBeenCalled(); 
}); 
); 
+0

THX @Jay,即幫我看看,我錯過了'{}'了'deferred.resolve內()'。這也適用於'it'。 所以解決方法是:'deferred.resolve({});' – escapedcat