Как выполнить модульное тестирование пользовательского фильтра $ путем насмешки в классе ES6 для углового контроллера
У меня есть класс ES, написанный для углового контроллера, и я пытаюсь написать жасминовые тесты, используя angular-mock.
В конструкторе я инициализирую $filter для this.i18n = $filter('i18n), который в основном является фильтром локализации, который принимает ключ, значение и возвращает локализованное значение для ключа.
Моя проблема заключается в том, что, поскольку конструктор класса имеет фильтр $, он впоследствии используется в методах класса. Мои юнит-тесты не пройдены. Как я могу проверить, используя $filter, чтобы мои тесты не провалились. Я ищу издеваться над пользовательским фильтром
Вот исключение, которое я получаю
TypeError: this.i18n is not a function
at UsersCtrl.$onInit (test-context.js:35081:41)
at Object.<anonymous> (test-context.js:35031:31)
Вот класс ES6
class UsersCtrl {
constructor($filter) {
this.i18n = $filter('i18n');
this.users = [];
}
//Life cycle Hooks: Initialization
$onInit() {
this.users = [
{name: this.i18n('USERS')}
];
}
}
UsersCtrl.$inject = ['$filter'];
angular.module('app', []).controller('UsersCtrl',UsersCtrl);
export default UsersCtrl;
Вот тестовый модуль, который у меня есть
Import UsersCtrl from './users-controller.js';
describe("given a new User Page", () => {
var UserController;
beforeEach(() => {
angular.mock.module('app');
});
describe("when initialising has completed", () => {
beforeEach(() => {
inject(($rootScope, $controller, $filter) => {
const scope = $rootScope.$new();
const filter = $filter
UserController = $controller("UsersCtrl", { $scope: scope, $filter: filter});
});
});
it("then users array for tab content should be empty initially",() => {
const expectedActive = [];
expect(UserController.users).toEqual(expectedActive);
});
});
});
Проблема в том, что он запускает тест, но не может его инициализировать с помощью this.i18n = $filter('i18n). Как мне инициализировать тест, чтобы передать $filter в тесты? Могу ли я издеваться над фильтром, так как я не хочу тестировать его здесь?
1 ответ
Вы можете либо:
- Издеваться над всем
$filter
обслуживать и вводить это в контроллер, когда вы создаете его в своем тесте; или же - Макет отдельного фильтра. Вы можете использовать
$provide.value(key, value)
когда вы загружаете свой модуль, где ключом является имя фильтра и суффикс: " Фильтр " (это то, что угловато делает при регистрации фильтров).
Пример обоих:
/* Angular App */
(function() {
"use strict";
class UsersCtrl {
constructor($filter) {
this.i18n = $filter('i18n');
this.users = [];
}
$onInit() {
this.users = [{
name: this.i18n('USERS')
}];
}
}
UsersCtrl.$inject = ['$filter'];
angular
.module('app', [])
.controller('UsersCtrl', UsersCtrl);
})();
/* Unit Test */
(function() {
"use strict";
describe('given a new User Page', () => {
let UsersController;
describe('MOCK entire $filter service: when initialising has completed', () => {
beforeEach(() => {
module('app');
inject(($rootScope, $controller) => {
UsersController = $controller("UsersCtrl", {
$scope: $rootScope.$new(),
$filter: () => {
// $filter will be a function that returns a noop function (or whatever we want)
return angular.noop;
}
});
});
});
it('then users array for tab content should be empty initially', () => {
const expectedActive = [];
expect(UsersController.users).toEqual(expectedActive);
});
});
describe('MOCK individual \'i18n\' filter: when initialising has completed', () => {
beforeEach(() => {
module('app', ($provide) => {
// provide a mock (noop function) for our filter.
// Note naming convention, our filter name + 'Filter' suffix.
$provide.value('i18nFilter', angular.noop);
});
inject(($rootScope, $controller, $filter) => {
UsersController = $controller("UsersCtrl", {
$scope: $rootScope.$new(),
$filter: $filter
});
});
});
it('then users array for tab content should be empty initially', () => {
const expectedActive = [];
expect(UsersController.users).toEqual(expectedActive);
});
});
});
})();
<link rel="stylesheet" href="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.css" />
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.js"></script>
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine-html.js"></script>
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/boot.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-mocks.js"></script>