단위 테스트 각도templateUrl이 있는 JS 디렉티브
각도 사용JS.
지시를 받다.
는 「」를 정의합니다.templateUrl
.
지시문에는 단위 테스트가 필요합니다.
현재 Jasmine과 유닛 테스트 중입니다.
이것은 다음과 같은 코드를 권장합니다.
describe('module: my.module', function () {
beforeEach(module('my.module'));
describe('my-directive directive', function () {
var scope, $compile;
beforeEach(inject(function (_$rootScope_, _$compile_, $injector) {
scope = _$rootScope_;
$compile = _$compile_;
$httpBackend = $injector.get('$httpBackend');
$httpBackend.whenGET('path/to/template.html').passThrough();
}));
describe('test', function () {
var element;
beforeEach(function () {
element = $compile(
'<my-directive></my-directive>')(scope);
angular.element(document.body).append(element);
});
afterEach(function () {
element.remove();
});
it('test', function () {
expect(element.html()).toBe('asdf');
});
});
});
});
재스민어로 된 실행 코드.
오류 발생:
TypeError: Object #<Object> has no method 'passThrough'
templateUrl을 있는 그대로 로드해야 합니다.
할 수 .respond
ngMockE2E가 아닌 ngMock 사용과 관련이 있을 수 있습니다.
ngMock과 관련된 은 모든 되며 모의 ngMock "Angular " "를 초기화합니다.$httpBackend
로도 사용할 수 .$http
fetchingservice: "template fetching.service: "template fetching." 가 포함됩니다..$http
그리고 그것은 모의에게 "의외의 요구"가 된다.
을 위해 $templateCache
Angular가때 Angular를 사용하지 할 수 .$http
.
바람직한 솔루션: Karma
Karma를 사용하여 테스트를 실행하는 경우(그럴 필요가 있습니다), ng-html2js 프리프로세서를 사용하여 템플릿을 로드하도록 설정할 수 있습니다.Ng-html2js는 사용자가 지정한HTML 파일을 읽고 그것들을 Angular 모듈로 변환하여$templateCache
.
1:를 유효하게 하여 합니다.karma.conf.js
// karma.conf.js
preprocessors: {
"path/to/templates/**/*.html": ["ng-html2js"]
},
ngHtml2JsPreprocessor: {
// If your build process changes the path to your templates,
// use stripPrefix and prependPrefix to adjust it.
stripPrefix: "source/path/to/templates/.*/",
prependPrefix: "web/path/to/templates/",
// the name of the Angular module to create
moduleName: "my.templates"
},
Yeoman을 사용하여 앱의 발판을 짜는 경우 이 구성이 작동합니다.
plugins: [
'karma-phantomjs-launcher',
'karma-jasmine',
'karma-ng-html2js-preprocessor'
],
preprocessors: {
'app/views/*.html': ['ng-html2js']
},
ngHtml2JsPreprocessor: {
stripPrefix: 'app/',
moduleName: 'my.templates'
},
순서 2: 테스트에서 모듈 사용
// my-test.js
beforeEach(module("my.templates")); // load new module containing templates
완전한 예로서 Angular test guru Vojta Jina의 이 표준적인 예를 참조하십시오.여기에는 카르마 설정, 템플릿 및 테스트의 전체 설정이 포함됩니다.
비 카르마 솔루션
하지 않은 때문에) 인수를 할 수 되었습니다.$httpBackend
XHR을 raw XHR에 하는 것으로 .$templateCache
이 솔루션은 유연성은 크게 떨어지지만, 현재는 작업이 완료됩니다.
// my-test.js
// Make template available to unit tests without Karma
//
// Disclaimer: Not using Karma may result in bad karma.
beforeEach(inject(function($templateCache) {
var directiveTemplate = null;
var req = new XMLHttpRequest();
req.onload = function() {
directiveTemplate = this.responseText;
};
// Note that the relative path may be different from your unit test HTML file.
// Using `false` as the third parameter to open() makes the operation synchronous.
// Gentle reminder that boolean parameters are not the best API choice.
req.open("get", "../../partials/directiveTemplate.html", false);
req.send();
$templateCache.put("partials/directiveTemplate.html", directiveTemplate);
}));
정말이야.업보를 이용하다.설정에는 약간의 작업이 필요하지만 명령줄에서 여러 브라우저에서 모든 테스트를 동시에 실행할 수 있습니다.따라서 연속 통합 시스템의 일부로 사용할 수도 있고 편집기에서 바로 가기 키로 사용할 수도 있습니다.alt-tab-refresh-ad-infinitum보다 훨씬 낫지
결국 템플릿 캐시를 가져와 뷰에 넣었습니다.ngMock을 사용하지 않을 수 없습니다.알고 보니 다음과 같습니다.
beforeEach(inject(function(_$rootScope_, _$compile_, $templateCache) {
$scope = _$rootScope_;
$compile = _$compile_;
$templateCache.put('path/to/template.html', '<div>Here goes the template</div>');
}));
이 초기 문제는 다음과 같이 추가함으로써 해결할 수 있습니다.
beforeEach(angular.mock.module('ngMockE2E'));
디폴트로는 ngMock 모듈에서 $httpBackend를 찾으려 하고, 꽉 차 있지 않기 때문입니다.
제가 도달한 솔루션은 jasmine-jquery.js와 프록시 서버가 필요합니다.
다음의 순서를 실행했습니다.
- 카르마.conf의 경우:
파일에 jasmine-jquery.module을 추가합니다.
files = [
JASMINE,
JASMINE_ADAPTER,
...,
jasmine-jquery-1.3.1,
...
]
고정 장치를 서버할 프록시 서버 추가
proxies = {
'/' : 'http://localhost:3502/'
};
사양대로
descript('MySpec', function() { var $temples, template; jasmine.getFiplates() ; //custom path = 'public/s/'; 커스텀 경로로 앱에서 사용하는 실제 템플릿을 각(' { template= angulate(') 전에 사용할 수 있습니다.
module('project'); inject(function($injector, $controller, $rootScope, $compile, $templateCache) { $templateCache.put('partials/resources-list.html', jasmine.getFixtures().getFixtureHtml_('resources-list.html')); //loadFixture function doesn't return a string $scope = $rootScope.$new(); $compile(template)($scope); $scope.$apply(); }) });
});
앱의 루트 디렉터리에서 서버 실행
python -m 심플HTTPServer 3502
업보를 하다.
많은 투고를 검색하지 않으면 안 되기 때문에 시간이 걸렸지만, 이것은 매우 중요한 문제이기 때문에, 그 문서는 더 명확해져야 한다고 생각합니다.
솔루션:
test/karma-utils.js
:
function httpGetSync(filePath) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/base/app/" + filePath, false);
xhr.send();
return xhr.responseText;
}
function preloadTemplate(path) {
return inject(function ($templateCache) {
var response = httpGetSync(path);
$templateCache.put(path, response);
});
}
karma.config.js
:
files: [
//(...)
'test/karma-utils.js',
'test/mock/**/*.js',
'test/spec/**/*.js'
],
테스트:
'use strict';
describe('Directive: gowiliEvent', function () {
// load the directive's module
beforeEach(module('frontendSrcApp'));
var element,
scope;
beforeEach(preloadTemplate('views/directives/event.html'));
beforeEach(inject(function ($rootScope) {
scope = $rootScope.$new();
}));
it('should exist', inject(function ($compile) {
element = angular.element('<event></-event>');
element = $compile(element)(scope);
scope.$digest();
expect(element.html()).toContain('div');
}));
});
Grunt를 사용하는 경우 grunt-angular-template를 사용할 수 있습니다.템플릿이 templateCache에 로드되고 사양 구성에 따라 투명해집니다.
설정 예:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
ngtemplates: {
myapp: {
options: {
base: 'public/partials',
prepend: 'partials/',
module: 'project'
},
src: 'public/partials/*.html',
dest: 'spec/javascripts/angular/helpers/templates.js'
}
},
watch: {
templates: {
files: ['public/partials/*.html'],
tasks: ['ngtemplates']
}
}
});
grunt.loadNpmTasks('grunt-angular-templates');
grunt.loadNpmTasks('grunt-contrib-watch');
};
저는 같은 문제를 선택한 해결책과는 조금 다른 방법으로 풀었습니다.
먼저 카르마용 ng-html2js 플러그인을 설치 및 구성하였습니다.karma.conf.js 파일에서 다음을 수행합니다.
preprocessors: { 'path/to/templates/**/*.html': 'ng-html2js' }, ngHtml2JsPreprocessor: { // you might need to strip the main directory prefix in the URL request stripPrefix: 'path/' }
그런 다음 각각에서 작성한 모듈을 로드했습니다.Spec.js 파일에서 다음을 수행합니다.
beforeEach(module('myApp', 'to/templates/myTemplate.html'));
그런 다음 $templateCache.get을 사용하여 변수에 저장합니다.Spec.js 파일에서 다음을 수행합니다.
var element, $scope, template; beforeEach(inject(function($rootScope, $compile, $templateCache) { $scope = $rootScope.$new(); element = $compile('<div my-directive></div>')($scope); template = $templateCache.get('to/templates/myTemplate.html'); $scope.$digest(); }));
마지막으로, 저는 이렇게 테스트했습니다.Spec.js 파일에서 다음을 수행합니다.
describe('element', function() { it('should contain the template', function() { expect(element.html()).toMatch(template); }); });
템플릿 html을 $templateCache에 동적으로 로드하려면 html2js 카르마 프리프로세서를 사용하면 됩니다(여기 설명 참조).
이는 conf.processors 파일의 파일에 템플릿 '.processors'를 추가하는 것과 프리프로세서 = {.processors': 'processors2params'};
및 사용
beforeEach(module('..'));
beforeEach(module('...html', '...html'));
js 테스트 파일에 저장
Karma를 사용하는 경우 Karma-ng-html2js-프리프로세서를 사용하여 외부 HTML 템플릿을 미리 컴파일하고 Angular가 테스트 실행 중에 HTTP GET을 시도하지 않도록 하십시오.앱과 테스트 디르 구조의 차이로 인해 저는 templateUrl의 일부 경로가 일반 앱 실행 중 해결되었지만 테스트 중에는 해결되지 않았습니다.
require와 함께 jasmine-maven-plugin을 사용하는 경우JS 텍스트 플러그인을 사용하여 템플릿 내용을 변수에 로드한 다음 템플릿 캐시에 넣을 수 있습니다.
define(['angular', 'text!path/to/template.html', 'angular-route', 'angular-mocks'], function(ng, directiveTemplate) {
"use strict";
describe('Directive TestSuite', function () {
beforeEach(inject(function( $templateCache) {
$templateCache.put("path/to/template.html", directiveTemplate);
}));
});
});
테스트에서 requirejs를 사용하는 경우 'text' 플러그인을 사용하여 HTML 템플릿을 가져와 $templateCache에 넣을 수 있습니다.
require(["text!template.html", "module-file"], function (templateHtml){
describe("Thing", function () {
var element, scope;
beforeEach(module('module'));
beforeEach(inject(function($templateCache, $rootScope, $compile){
// VOILA!
$templateCache.put('/path/to/the/template.html', templateHtml);
element = angular.element('<my-thing></my-thing>');
scope = $rootScope;
$compile(element)(scope);
scope.$digest();
}));
});
});
이 문제를 해결하려면 모든 템플릿을 템플릿 캐시에 컴파일합니다.저는 꿀꺽꿀꺽 마시고 있어요, 투덜거릴 때도 비슷한 용액을 찾을 수 있을 거예요.my templateUrls in Directive, modals는
`templateUrl: '/templates/directives/sidebar/tree.html'`
패키지에 새로운 npm 패키지를 추가합니다.json
"gulp-angular-templatecache": "1.*"
gulp 파일에서 템플릿 캐시와 새 작업을 추가합니다.
var templateCache = require('gulp-angular-templatecache'); ... ... gulp.task('compileTemplates', function () { gulp.src([ './app/templates/**/*.html' ]).pipe(templateCache('templates.js', { transformUrl: function (url) { return '/templates/' + url; } })) .pipe(gulp.dest('wwwroot/assets/js')); });
index.html에 모든 js 파일을 추가합니다.
<script src="/assets/js/lib.js"></script> <script src="/assets/js/app.js"></script> <script src="/assets/js/templates.js"></script>
맛있게 드세요!
언급URL : https://stackoverflow.com/questions/15214760/unit-testing-angularjs-directive-with-templateurl
'source' 카테고리의 다른 글
Angular.js에서 AJAX 콜을 발신하기 위한 베스트 프랙티스는 무엇입니까? (0) | 2023.03.15 |
---|---|
Yoast SEO 플러그인에 의해 추가된 rel canical을 제거하는 중 (0) | 2023.03.15 |
Angular JS - 오염되지 않은 것과 만져지지 않은 것의 차이 (0) | 2023.03.15 |
JSON, REST, SOAP, WSDL 및 SOA: 이 모든 것을 함께 연결하는 방법 (0) | 2023.03.15 |
XML 태그 속성을 JSON으로 어떻게 표현합니까? (0) | 2023.03.10 |