我正在为下面的控制器编写单元测试。我有两个函数loadCountries和loadTimezones我想在页面加载时调用。我想测试国家是否在页面加载时加载。在那个特定的测试中,我不关心时区是否被加载。所以我嘲笑了Timezones服务。但看起来我已经为时区mock返回了一个值。我不想明确地处理它。我期待当我创建SpyObj时,任何未在spy / mock上显式处理的函数调用都将被删除或无效。如果我不链接returnValue,mock就是调用实际函数。我该如何解决这个问题?
'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 :(得分:0)
这里不可能摆脱and.returnValue
,因为控制器链接一个promise并期望Timezone.getTimezones
stub返回的对象上的方法(并且它不返回)。
jasmine.createSpyObj
仅处理对Timezone
方法的调用,而不处理其返回值,这就是and.returnValue
存在的原因。
完全没问题
MockTimezone.getTimezones.and.returnValue($q.resolve({}));
基于承诺的规范。