2013-07-22 73 views
1

我試圖通過傳遞虛擬版本的服務來測試我的控制器。然而,當業力運行時,它會調用真正的服務,這是在控制器定義(第3行)中指定的,而不是我試圖注入的對象beforeEach(inject(function(....)在單元測試中將虛擬版本的服務傳遞給控制器​​

請幫助我確定我做錯了什麼。

//I have a code like the following. 
angular.module('myApp') 
    .controller('memberSearch2Ctrl', ['$scope', 'PersonnelService', 'SavedSearchService', '$routeParams', '$log', 
     function memberSearch2Ctrl($scope, personnelApi, savedSearches, $routeParams, $log) { 
      // utilises PersonnelService to make ajax calls to get data from server.... 
     } 
    ]); 

// real version of a service that makes ajax calls and returns real data 
angular.module('myApp') 
    .service('PersonnelService', function($http, $q) { 
     //this.search(....) 
    }); 

// dummy version of the above, has the same functions like above just returns hardcoded json 
angular.module('myApp') 
    .service('PersonnelServiceMock', function($http, $q) { 
     // returns hardcoded json for testing purpose 
     //this.search(....) 
    }); 


// heres my tests 
describe('memberSearch2Ctrl', function() { 
    var ctrl, scope, personnelApiMock, savedSearchService; 

    beforeEach(module('myApp')); 
    beforeEach(inject(function($rootScope, $controller, PersonnelServiceMock, SavedSearchService, $log) { 

     personnelApiMock = PersonnelServiceMock; // this sets the PersonnelServiceMock correctly 
     console.log(JSON.stringify(PersonnelServiceMock)); // as I see in this line 
     console.log(JSON.stringify(SavedSearchService)); 


     scope = $rootScope.$new(); 
     ctrl = $controller('memberSearch2Ctrl', { 
      $scope: scope, 
      personnelApi: PersonnelServiceMock, 
      savedSearches: SavedSearchService, 
      $routeParams: {}, 
      $log: $log 
     }); 

    })); 

    iit('upon search $scope.searchResults = PersonnelService.searchPaged(...)', function() { 
     // however problem lies in the next line 
     scope.search(); // this calls PersonnelService.search insted of PersonnelServiceMock.search 
     // even when I have beforeEach(inject(function($rootScope, $controller, >>> PersonnelServiceMock <<<, 
     scope.$root.$digest(); 

     var expected = personnelApiMock.searchPaged(null, null, null); 
     var actual = scope.searchResults; 
     expect(actual).toEqual(expected); 
    }); 
}); 

嘗試在$ injector中傳遞並使用injector實例化PersonnelServiceMock。 控制檯日誌說我實際上得到PersonnelServiceMock作爲回報。但仍嘗試在PersonnelService中定義ajax調用

beforeEach(inject(function($rootScope, $controller, $injector) { 

    personnelApiMock = $injector.get('PersonnelServiceMock'); 
    savedSearchService = $injector.get('SavedSearchService'); 
    log = $injector.get('$log'); 

    console.log(JSON.stringify(personnelApiMock)); 
    console.log('=========================================='); 
    console.log(JSON.stringify(savedSearchService)); 
    console.log('******************************************'); 

    scope = $rootScope.$new(); 
    ctrl = $controller('memberSearch2Ctrl', { 
     $scope: scope, 
     personnelApi: personnelApiMock, 
     savedSearches: savedSearchService, 
     $routeParams: {}, 
     $log: log 
    }); 

}));

好像在調用ctrl = $controller('memberSearch2Ctrl', { ...})時指定的內容被忽略,並且正在使用控制器定義(行〜3)中指定的內容。

回答

1

問題是這段代碼:

ctrl = $controller('memberSearch2Ctrl', { 
    $scope: scope, 
    personnelApi: PersonnelServiceMock, <!--- 
    savedSearches: SavedSearchService, 
    $routeParams: {}, 
    $log: $log 
}); 

應該是:

ctrl = $controller('memberSearch2Ctrl', { 
    $scope: scope, 
    PersonnelService: PersonnelServiceMock, <!--- 
    savedSearches: SavedSearchService, 
    $routeParams: {}, 
    $log: $log 
}); 
+0

非常感謝!接受這個答案...所以我應該一直使用的依賴項的名稱,而不是在函數參數列表中的實際變量名稱!再次感謝! –

+0

是的,如果你使用數組方法簽名來聲明依賴注入。顯然,如果你不是,那麼依賴項的名稱和實際變量名是一樣的。 –

相關問題