Я пытаюсь выполнить единую тестовую угловую директиву с внешним шаблоном. Пример кода приведен ниже.
var vsLogin = angular.module('vs-login', []);
vsLogin.directive('vsLogin', function (vsLoginService, dataService, applicationService, $state, viewService, vsModaldialogService, utilsService) {
return {
restrict: 'E',
replace: true,
scope: {
templateurl: "@",
loginDomain: "=?",
loginid: "=?",
loggedInUser: "=?"
},
controller: ['$scope', function ($scope) {
$scope.errorMsg = '';
$scope.status = {};
applicationService.clearLocalCache();
$scope.login = function (domain, loginid, password) {
if ( loginid === undefined || password === undefined || loginid.trim() === ''|| password.trim() === '') {
$scope.errorMsg = 'The login ID or password entered is invalid. Please try again.';
}
// verify the form is valid
if (!utilsService.isFormValid('merchant-login-form')) {
return;
}
var promise = vsLoginService.login(domain, loginid, password);
promise.then(function (res) {
// success
}
, function (res) {
// fail
});
}
}],
templateUrl: function (element, attrs) {
if (attrs.templateurl) {
return attrs.templateurl;
}
return viewService.getWidgetTemplateUrl("Login");
}
}
})
Тест-код с использованием Jasmine + Chutz-pah выглядит следующим образом.
/// <template path="./Login.cshtml" />
/// <reference path="./jquery-2.1.4.js" />
/// <chutzpah_reference path="./angular.min.js" />
/// <chutzpah_reference path="./angular-mock.js" />
/// <chutzpah_reference path="./jasmine.js" />
/// <chutzpah_reference path="./jasmine-html.js" />
/// <chutzpah_reference path="./blanket.js" />
/// <chutzpah_reference path="./Application.js" />
/// <chutzpah_reference path="./DataService.js" />
/// <chutzpah_reference path="./LoginService.js" />
/// <chutzpah_reference path="./ModalDialogService.js" />
/// <chutzpah_reference path="./uiFormValidation.js" />
/// <chutzpah_reference path="./utilsService.js" />
/// <chutzpah_reference path="./ViewService.js" />
/// <chutzpah_reference path="./stateMock.js" />
/// <chutzpah_reference path="./Login.js" />
describe("LoginTest with loginid and password", function () {
var $rootScope, $compile, element, scope, state, controller;
angular.module("vs-login", ["vsLogin"]);
beforeEach(function () {
module('stateMock');
module('uiFormValidation.services');
module(function ($provide) {
$provide.value('vsLoginService', vsLoginService);
$provide.value('dataService', dataService);
$provide.value('applicationService', applicationService);
$provide.value('viewService', viewService);
$provide.value('vsModaldialogService', vsModaldialogService);
});
inject(function ($injector, $rootScope, $controller, $httpBackend, $templateCache) {
var template = jQuery(".merch-login-form")[0].outerHTML;
$templateCache.put("/Login.cshtml", template);
$compile = $injector.get('$compile');
scope = $rootScope.$new();
element = angular.element("<div ng-app='appname'><vs-login loginDomain='somedomain' loginid='someuser'></vs-login></div>");
element = $compile(element)(scope);
scope.$digest();
controller = element.controller;
var html = element.html();
var directiveScope = element.isolateScope();
});
});
Проблема здесь заключается в том, что isolateScope всегда приходит неопределенным и не может проверить метод внутри области [т.е. метод scope.login].
Пожалуйста, предложите.
Я решил проблему. Я отделил контроллер от директивы и передал именованный контроллер для проверки, чтобы получить область внутри тестового примера.
Что вы ожидаете от jQuery(".merch-login-form")[0].outerHTML
для возврата? Во время модульного тестирования у вас нет (или, по крайней мере, не должен) рабочего DOM, он должен быть просто пустым.
Однако вам не нужно отправлять весь шаблон по вашему модульному тесту, вы можете кэшировать посмеянный шаблон, который может дать вам простой и быстрый способ проверить эту директиву.
например: если ваш реальный шаблон - это что-то вроде
<h1>This is my title: {{title}}!!!!</h1>
<h2>This is my subtitle: {{subtitle}}!!!!</h2>
вы можете просто проверить директиву с помощью шаблона, например
{{title}},{{subtitle}}
так как оба имеют одно и то же поведение, но во втором легче разбираться с javscript