2015-12-21 2 views
1

Я пытаюсь протестировать контроллер, который использует синтаксис controllerAs. Моя проблема в том, что когда я пытаюсь проверить функцию на контроллере, я получаю «Ожидаемое неопределенное, чтобы быть определенным».Контрольный модуль для тестирования единиц измерения: контроллер протоколирования возвращает обещание

Controller (сокращенный вариант)

(function (angular) { 
    'use strict'; 

    /* @ngInject */ 
    function PreflightCtrl($state, $window, $timeout, $stateParams, toastr, accountService, servicesService, geoService, visitService, localStorageService, Notifications, service, UTILS) { 

    /* Exported Vars */ 
    var vm = this; 

    /* Exported functions */ 
    vm.verifyDob = verifyDob; 

    function verifyDob() { 
     if (!vm.form.dob || (vm.form.dob.length !== 8 && vm.form.dob.length !== 10)){ 
     return; 
     } 
     if(vm.form.dob.length === 8){ 
     var lastTwoDigits = vm.form.dob.substr(vm.form.dob.length-2); 
     if(lastTwoDigits === '19'){ 
      return; 
     } 
     } 
     var dob = new Date(vm.form.dob); 
     vm.verifyingDob = true; 
     accountService.verifyDOB(dob) 
     .success(function(data){ 
      vm.genderDisabled = false; 
      vm.dobError = false; 
      $timeout(function() { 
      dobInput.blur(); 
      }); 
     }) 
     .error(function (status) { 
      vm.genderDisabled = true; 
      vm.dobError = true; 
     }) 
     .finally(function() { 
      vm.verifyingDob = false; 
     }); 
    } 
    } 

    angular 
    .module('app') 
    .controller('PreflightCtrl', PreflightCtrl); 

}(angular)); 

Тест

describe('PreflightCtrl', function(){ 
    var PreflightCtrl, $state, $window, $timeout, $stateParams, toastr, accountService, servicesService, geoService, visitService, localStorageService, Notifications, service, UTILS, mockAccountService, mockServicesService; 

    beforeEach(module('app')); 

    beforeEach(inject(function($controller, _$state_, _$window_, _$timeout_, _$stateParams_, _toastr_, _accountService_, _servicesService_, _geoService_, _visitService_, _localStorageService_, _Notifications_, _UTILS_){ 

    //mock services used in PreflightCtrl 
    mockAccountService = { 
     verifyDOB: function verifyDOB(dob){ 
     return { 
      success: function(callback){ 
      callback(dob); 
      } 
     } 
     }, 
     isPermUser: function isPermUser(){ 
     return { 
      success: function(callback){ 
      callback(true); 
      } 
     } 
     }, 
     profile: { 
     gender: 'male' 
     } 
    }; 

    mockServicesService = { 
     isGenderAllowed: function isGenderAllowed(serviceCode, gender){ 
     return true; 
     } 
    } 

    //prepare for dependency injection 
    $state = _$state_; 
    $window = _$window_; 
    $timeout = _$timeout_; 
    $stateParams = _$stateParams_; 
    toastr = _toastr_; 
    accountService = mockAccountService; 
    servicesService = mockServicesService; 
    geoService = _geoService_; 
    visitService = _visitService_; 
    localStorageService = _localStorageService_; 
    Notifications = _Notifications_; 
    service = {"id": 3, "code": "HL", "flags": {"multi_medicine": false}, "genders": ["male"], "name": "Hair Loss", "product": {"count": 3}, "visible": 1}; 
    UTILS = _UTILS_; 

    //spy on the mocked services 
    spyOn(accountService, 'verifyDOB').and.callThrough(); 
    spyOn(servicesService, 'isGenderAllowed').and.callThrough(); 

    //create the controller 
    PreflightCtrl = $controller('PreflightCtrl', { 
     $state: $state, 
     $window: $window, 
     $timeout: $timeout, 
     $stateParams: $stateParams, 
     toastr: toastr, 
     accountService: accountService, 
     servicesService: servicesService, 
     geoService: geoService, 
     visitService: visitService, 
     localStorageService: localStorageService, 
     Notifications: Notifications, 
     service: service, 
     UTILS: UTILS 
    }); 

    })); 

    it('should have a defined controller', function(){ 
    expect(PreflightCtrl).toBeDefined(); 
    }); 

    it('should have a defined function called verifyDob', function(){ 
    console.log(PreflightCtrl); 
    expect(PreflightCtrl.verifyDob).toBeDefined(); 
    }); 

    it('should verify a DOB', function(){ 

    PreflightCtrl.form.dob = '01/01/1990'; 
    PreflightCtrl.verifyDob(); 
    expect(PreflightCtrl.verifyingDob).toBe(false); 
    }); 
}); 

Когда я запускаю тест, это выход, который я получаю:

Запуск «карма: unit "(карма) PhantomJS 1.9.8 (Mac OS X 0.0.0) LOG: 'ПРЕДУПРЕЖДЕНИЕ: Пытался нагружать углы более одного раза.

LOG: Promise {$$ state: Object {status: 2, value: Error {message: ...}}} PhantomJS 1.9.8 (Mac OS X 0.0.0) PreflightCtrl должен иметь определенную функцию, называемую verifyDob FAILED Ожидаемое неопределенное определение. в /Users/tracy/Projects/LemonaidClinic/src/views/preflight/preflight.controller.spec.js:80 PhantomJS 1.9.8 (Mac OS X 0.0.0) PreflightCtrl должен проверить DOB FAILED TypeError: 'undefined 'не является объектом (оценка' PreflightCtrl.form.dob = '01/01/1990 '') в /Users/tracy/Projects/LemonaidClinic/src/views/preflight/preflight.controller.spec.js:85 PhantomJS 1.9.8 (Mac OS X 0.0.0): Выполнено 15 из 15 (2 НЕИСПРАВНОСТИ) (0,006 сек/0,204 с) Предупреждение: Задача «Карма: единица» не удалась. Используйте -force для продолжения.

Прервано из-за предупреждений.

Строка 80 - это линия: ожидать (PreflightCtrl.verifyDob) .toBeDefined();

и строка 85: PreflightCtrl.form.dob = '01/01/1990 ';

, и вы можете видеть первую строку, это журнал контроллера, который возвращает обещание, которое означает, что ни одна из функций или переменных не находится на контроллере, который должен быть там.

Я также не уверен, почему Angular пытается загрузить более одного раза, но, похоже, это не влияет на другие тесты.

Что я делаю неправильно?

Заранее спасибо.

+0

Я думаю, что контроллер не существует до тех пор, пока вы не назовете $ rootScope. $ Apply(). Кроме того, вам не нужно вручную вводить каждую зависимость. Угловой будет вводить те, которые у него есть, если вы не настраиваете/не переопределяете их в тесте. –

+0

Где я могу добавить $ rootScope. $ Apply()? Единственными зависимостями, которые я создал вручную, были те, которые вызывали ошибки при запуске тестов, и создание этих издевающихся зависимостей исправляет эти ошибки, поэтому я предполагаю, что они необходимы ... –

ответ

0

Я хотел бы сделать это примерно так:

 
var scope = $rootScope.$new(); 

$controller('myController as vm', {$scope:scope, /*your dependency tree hell*/}); 
$rootScope.$apply(); 

vm = scope.vm;//This is your new controller, you can refer to it in tests. 

Я думаю, тот факт, что вы должны издеваться так много говорит ваш контроллер имеет слишком много зависимостей, прямо и/или косвенно.

Однако, если вы не в состоянии исправить это, вы можете легко высмеять, просто создав папку «mocks» и отбросьте файлы, имеющие тот же идентификатор, что и реальные, и указав Карму на это папка. Они переопределяют фактические зависимости. Недостатком является то, что вам все равно придется делать одноразовые макеты, если вам нужно что-то другое, чем ваш зарегистрированный макет, но он устраняет задачу настройки макетов в каждом тесте.