2016-02-05 62 views
2

我正在编写一个单元测试下面的控制器。我有两个函数loadCountries和loadTimezones,我想在页面加载时调用它。我想测试一下在页面加载时加载的国家。在特定的测试中,我不在乎时区是否加载。所以我嘲笑时区服务。但看起来我必须为时区模拟返回一个值。我不想明确处理它。我期待在创建SpyObj时,任何未在间谍/模拟上明确处理的函数调用都将被删除或不起作用。如果我不连锁returnValue,模拟正在调用真正的功能。我该如何解决 ?如何嘲笑使用茉莉花服务忽略任何电话

'use strict'; 

angular.module('nileLeApp') 
.controller('RegisterController', function ($scope, $translate, $timeout, vcRecaptchaService, Auth, Country, Timezone, RecaptchaService) { 
    $scope.success = null; 
    $scope.error = null; 
    $scope.doNotMatch = null; 
    $scope.errorUserExists = null; 
    $scope.registerAccount = {}; 
    $timeout(function() { 
     angular.element('[ng-model="registerAccount.email"]').focus(); 
    }); 

    $scope.loadCountries = function() { 
     Country.getCountries() 
      .then(function (result) { 
       $scope.countries = result.data; 
      }); 
    }; 

    $scope.loadTimezones = function() { 
     Timezone.getTimezones() 
      .then(function (result) { 
       $scope.timezones = result.data; 
      }); 
    }; 

    $scope.loadCountries(); 
    $scope.loadTimezones(); 
}); 

以下是我正在尝试的测试。

'use strict'; 

describe('Register Controllers Tests', function() { 

describe('RegisterController', function() { 

    // actual implementations 
    var $scope; 
    var $q; 
    // mocks 
    var MockTimeout; 
    var MockTranslate; 
    var MockAuth; 
    var MockCountry; 
    var MockTimezone; 
    // local utility function 
    var createController; 

    beforeEach(inject(function ($injector) { 
     $q = $injector.get('$q'); 
     $scope = $injector.get('$rootScope').$new(); 
     MockTimeout = jasmine.createSpy('MockTimeout'); 
     MockAuth = jasmine.createSpyObj('MockAuth', ['createAccount']); 
     MockCountry = jasmine.createSpyObj('MockCountry', ['getCountries']); 
     MockTimezone = jasmine.createSpyObj('MockTimezone', ['getTimezones']); 
     MockTranslate = jasmine.createSpyObj('MockTranslate', ['use']); 


     var locals = { 
      '$scope': $scope, 
      '$translate': MockTranslate, 
      '$timeout': MockTimeout, 
      'Auth': MockAuth, 
      'Country': MockCountry, 
      'Timezone': MockTimezone 
     }; 
     createController = function() { 
      $injector.get('$controller')('RegisterController', locals); 
     }; 
    })); 

    it('should load countries on page load', function() { 

     var mockCountryResponse = {data: [{ 
      'countryId': 1, 
      'alpha2Code': "AF", 
      'countryName': "Afghanistan" 
     }]}; 

     MockCountry.getCountries.and.returnValue($q.resolve(mockCountryResponse.data)); 
     // Want to avoid explicitly specifying below line    
     MockTimezone.getTimezones.and.returnValue($q.resolve({})); 

     // given 
     createController(); 

     $scope.$apply($scope.loadCountries); 
     expect($scope.countries).toEqual(mockCountryResponse); 
    }); 

}); 

回答

0

这是不可能摆脱and.returnValue这里,因为控制器链的承诺,并期望对象Timezone.getTimezones存根将返回的方法(和它返回无)。

jasmine.createSpyObj只处理对Timezone方法的调用,而不是它们的返回值,这就是为什么and.returnValue在那里。

这是完全细做

MockTimezone.getTimezones.and.returnValue($q.resolve({})); 

基于承诺,规范。