在我的Mocha测试中,Angular Controller Mock没有持续存在

Angular Controller Mock is not perisisting in my Mocha test

本文关键字:Mock 存在 Controller Angular Mocha 我的 测试      更新时间:2023-09-26

当前运行Angular 1.2。X与业力摩卡0.2.0和业力chai 0.1.0。

下面是我试图为我的MentorAvailabilityDashboardCtrl写一些简单的单元测试,这是基于Mentors模块。当单独运行时,一切都通过,但当我运行测试时,我得到一个错误,说明"错误:[ng:areq]参数'MentorAvailabilityDashboardCtrl'不是一个函数,得到未定义"

这让我认为Mocha或AngularMock在测试运行一次后被重置,并且之后未定义。

例子:

测试一次全部运行

  • 第一次测试=通过
  • 第二次测试=失败"MentorAvailabilityDashboardCtrl got undefined"
  • 第三次测试=失败"MentorAvailabilityDashboardCtrl got undefined"
  • 第4次测试=失败"MentorAvailabilityDashboardCtrl got undefined"

测试一次运行所有测试(注释掉其他测试)

  • 第一次测试=通过
  • 第二次测试=通过
  • 第三次测试=通过
  • 第4次测试=通过

问题:

为什么我的控制器在第一次测试运行后未定义,我能做些什么让它在每次测试运行中持续存在?

我代码:

'use strict';
/* globals gon: false */
import angular from 'angular';
describe('MentorAvailabilityDashboardCtrl', function() {
  let createController, $scope;
  beforeEach(function() {
    angular.module('Mentors', []);
    require('./mentor_availability_dashboard')
    angular.mock.module('Mentors');
  });
  beforeEach(angular.mock.inject(function ($rootScope, $controller) {
      function MockMentorProfile() {}
      function MockFlash() {}
      $scope = $rootScope.$new()
      createController = $controller('MentorAvailabilityDashboardCtrl', {
        $scope: $scope,
        MentorProfile: MockMentorProfile,
        Flash: MockFlash
      });
  }));
  describe('validation checks', function() {
    it('should invalidate form fields on initialization', function() {
      expect($scope.validatedFields()).to.eq(false);
    });
    it('should validate specifc field on initialization', function() {
      $scope.courseFilter = 'Rails';
      expect($scope.fieldValidated($scope.courseFilter)).to.eq(true);
    });
    it('should validate form fields on completion', function() {
      $scope.courseFilter = 'Rails';
      $scope.osFilter = 'Windows';
      $scope.studentFilter = { student: 'Billy' };
      $scope.paceFilter = '12 weeks';
      $scope.startFilter = { monday: 'Monday' };
      expect($scope.validatedFields()).to.eq(true);
    });
    it('should be able to click form with clearForm()', function() {
      $scope.courseFilter = 'Rails';
      $scope.clearForm()
      expect($scope.courseFilter).to.eq('');
    });
  });
});
实际错误:

PhantomJS 1.9.8 (Mac OS X 0.0.0) MentorAvailabilityDashboardCtrl "before each" hook: workFn for "should validate specifc field on initialization" FAILED
    Error: [ng:areq] Argument 'MentorAvailabilityDashboardCtrl' is not a function, got undefined
    http://errors.angularjs.org/1.2.26/ng/areq?p0=MentorAvailabilityDashboardCtrl&p1=not%20a%20function%2C%20got%20undefined
        at assertArg (/Users/bdoug/Bloc/vendor/assets/bower_components/angular/angular.js:1509)
        at assertArgFn (/Users/bdoug/Bloc/vendor/assets/bower_components/angular/angular.js:1520)
        at /Users/bdoug/Bloc/vendor/assets/bower_components/angular/angular.js:7278
        at /Users/bdoug/Bloc/frontend/test/tests_index.js:15072 <- webpack:///frontend/legacy_org/mentors/mentor_availability_dashboard.test.js:23:8
        at invoke (/Users/bdoug/Bloc/vendor/assets/bower_components/angular/angular.js:3966)
        at workFn (/Users/bdoug/Bloc/vendor/assets/bower_components/angular-mocks/angular-mocks.js:2161)

看起来您需要在beforeEach块中的控制器定义,这可能与它有关。可能是范围问题。你可以尝试避免所有的角模拟,直接测试控制器功能。因为你使用的是es6模块,所以你可以直接将控制器函数导出为命名的export。

export function MyController($scope, Flash) {
 //...
}
MyController.$inject = ['$scope', 'Flash'];
angular.module('Mentors').controller('MyController')

然后在测试

import sinon from 'sinon';
import {MyController} from './my_controller'

it('...', function() {
  let scope = {};
  let Flash = sinon.mock();
  MyController(scope, Flash);
  //... assertions
})