angularjs - ¿Cómo puedo probar una directiva usando templateUrl en el navegador sin cabeza de Chutzpah?
jasmine (6)
¿Alguien sabe cómo obtener un navegador sin cabeza como el Visual Studio Test Adapter de Chutzpah para permitir que una directiva acceda a su archivo de plantilla .html? Chutzpah usa PhantomJS para un navegador sin cabeza que parece limitar mis opciones.
Estoy usando Chutzpah Test Adapter 2.5 y AngularJS 1.2.0-r.2.
Me sale el error:
Solicitud inesperada: GET myApp / directives / template.html
Esto se debe a que Angular intentó usar el servicio $ http para acceder a la plantilla de mi directiva.
He encontrado algunas soluciones diferentes:
- Manualmente usando XMLHttpRequest para importar las plantillas.
- Usando una utilidad como Grunt para alinear la plantilla en el código JS de su directiva.
-
$httpBackend.when(''GET'', ''myApp/directives/template.html'').passThrough()
- esto solo funciona en pruebas e2e, no en pruebas unitarias. - Coloque la plantilla directamente en el código de prueba.
Ninguna de estas opciones en particular me satisface. Preferiría poder dejar que la directiva cargue su plantilla de forma transparente para que pueda probarla como un componente. ¿Hay alguna manera de que pueda funcionar este escenario?
Código de ejemplo:
angular.module(''myDirective'', []).directive(''myDirective'', function() {
return {
restrict: ''E'',
transclude: true,
templateUrl: ''myApp/directives/template.html'',
// Some other options, omitted for brevity.
};
});
template.html:
<div><div ng-transclude></div></div>
Ejemplo de prueba de jazmín:
describe(''myDirective'', function() {
// Assign $scope using inject(), load module etc.
// Insert workaround for $httpBackend loading my templateUrl here.
it(''should transclude content'', function() {
var element = $compile("<my-directive>Look Mom, I''m in my directive!</my-directive>")($scope);
$scope.$digest();
expect(element.text().trim()).toBe("Look Mom, I''m in my directive!");
});
}
Asegúrese de incluir su plantilla en su inyector antes de que se cree. Entonces intenta,
beforeEach(module(''myApp/directives/template.html'');
Tuve un problema similar tratando de probar mis directivas. Encontré una solución usando el patrón de https://github.com/vojtajina/ng-directive-testing .
Paso 1: utilice el complemento ng-html2js para compilar la plantilla angular en JavaScript Paso 2: haga clic en la respuesta respondida anterior e inclúyala como módulo en su antes de cada una.
ng-html2js también le permite realizar una manipulación personalizada de la ''url'' que espera que podría ser útil si su directorio de prueba no es el mismo que el directorio de su aplicación.
Usando ng-html2js este es un gran video que muestra cómo configurarlo para probar la directiva templateUrl. No estoy seguro de cuán aplicable es esto para Chutzpah, ya que este es un ejemplo de Karma, ¡pero podría llevarte en la dirección correcta!
Logré ponerlo en funcionamiento, usando la opción de compilación de Chutzpah. Transmití karma-ng-html2js-preprocessor en un script de PowerShell y luego lo invoqué desde Chutzpah para compilar el HTML en archivos JS.
Se agregó una secuencia de comandos de PowerShell junto al archivo de configuración chutzpah.json (la secuencia de comandos siguiente contiene compatibilidad no comprobada para PreprendPrefix y StripSuffix)
# PowerShell port of https://github.com/karma-runner/karma-ng-html2js-preprocessor
Param (
[parameter(Mandatory=$true)] [string] $Path,
[string] $Module = '''',
[string] $StripPrefix = '''',
[string] $PrependPrefix = '''',
[string] $StripSuffix = ''''
)
Function EscapeContent($content) {
$content -replace "//", "////" -replace "''", "/'" -replace "`r?`n", "/n'' +`n ''"
}
Function Rename($fileName) {
"$PrependPrefix" + ("$fileName" -replace "$StripPrefix", '''' -replace "$StripSuffix", '''' -replace "//", "/")
}
$Template = If ("$Module" -eq "") {
"angular.module(''{0}'', []).run(function(`$templateCache) {{`n" `
+ " `$templateCache.put(''{0}'',`n ''{2}'');`n" `
+ "}});`n"
} Else {
"(function(module) {{`n" `
+ "try {{`n" `
+ " module = angular.module(''{1}'');`n" `
+ "}} catch (e) {{`n" `
+ " module = angular.module(''{1}'', []);`n" `
+ "}}`n" `
+ "module.run(function(`$templateCache) {{`n" `
+ " `$templateCache.put(''{0}'',`n ''{2}'');`n" `
+ "}});`n" `
+ "}})();`n"
}
Get-ChildItem $Path -Recurse -Filter *.html | Foreach-Object {
$content = Get-Content $_.FullName | Out-String
$content = EscapeContent $content
$fileName = Rename "$($_.FullName)"
("$Template" -f "$fileName", "$Module", "$content") | Set-Content "$($_.FullName).js"
}
Se agregó la configuración de compilación a chutzpah.json y se agregaron los archivos JS "compilados" a Referencias (la referencia podría ser agregada desde el archivo de prueba, pero prefiero usar chutzpah.json para administrar todas las referencias)
{
"References": [
{ "Path": "./path/to/templates/", "Include": "*.html.js" },
],
"Compile": {
"Extensions": [".html"],
"ExtensionsWithNoOutput": [".html.js"],
"SourceDirectory": "./path/to/templates",
"OutDirectory": "./path/to/templates",
"Executable": "%powershellexe%",
"Arguments": "-NoProfile %chutzpahsettingsdir%//chutzpah-ng-html2js-compiler.ps1 -Path ''/path/to/templates/'' -Module ''templates'' -StripPrefix ''.+(?=////templates)''"
}
}
En sus archivos de prueba, cargue el módulo, en mi caso, todos están en el módulo ''plantillas''
beforeEach(module(''templates''));
// or alternatively
beforeEach(module(''/path/to/templates/foo.html''));
puedes usar la referencia de "plantilla" de Chutzpah
http://matthewmanela.com/blog/chutzpah-2-4-2/
/// <template path="../../MvcAngularJs1_3/ScriptsApp/directives/Templates/testTemplate.html" />
/// <reference path="../../mvcangularjs1_3/scripts/jquery-2.1.1.js" />
/// <reference path="../../mvcangularjs1_3/scripts/angular.js" />
/// <reference path="../../mvcangularjs1_3/scripts/angular-mocks.js" />
...
bajo las referencias, entonces Chutzpah incluye el HTML directamente en el archivo HTML de prueba. Le he dado a mis plantillas una clase css única para encontrarlas y ponerlas a mano en la caché de plantillas Template AngularJS.
mi plantilla HTML
<div class="row templateTestTemplate">
<div class="col-lg-12">
<h1>Tempalte Test</h1>
</div>
</div>
la directiva
angular.module("testTemplateDirective", [])
.directive("testTemplate", function() {
return {
restrict: ''A'',
replace: true,
templateUrl: ''ScriptsApp/directives/Templates/testTemplate.html''
}
});
en mi unidad Pruebas Estoy usando jQuery para encontrar la Plantilla y agregarla a la Plantilla de Caché. Angular first se ve en la plantilla caché y no hace una llamada HTTP.
var template = jQuery(".templateTestTemplate")[0].outerHTML;
$templateCache.put("ScriptsApp/directives/Templates/testTemplate.html", template);
Eso funciona muy bien hasta ahora, pero solo funciona con chutzpah, cuando ejecuta esta prueba con Resharper la prueba fallará, porque resharper no copia la plantilla en el HTML de prueba.
También abrí una solicitud en la página Chutzpah GitHub para rodear el HTML con etiquetas de scripts y una identificación para que no necesites extender la plantilla https://github.com/mmanela/chutzpah/issues/330
Puede usar jazmín-jquery para cargar contenido del archivo o http en $ templateCache. Funciona en Chutzpah sin modificaciones.
Primero agrega jasmine-jquery a tu proyecto y agrega chutzpah.json Referencias:
(de mi código)
"References" : [
{"Path" : "vendor/jasmine-jquery-2.1.0.js"}
]
Luego, en su prueba, inyecte $ templateCache y cárguelo con contenido "en vivo" a través de jasmine.getFixtures () de la siguiente manera:
beforeEach(inject(function ($templateCache) {
//Loading template from live develop server
jasmine.getFixtures().fixturesPath = "http://localhost:47152";
var templateUrl = "/myApp/directives/template.html";
$templateCache.put(templateUrl, jasmine.getFixtures()
.getFixtureHtml_(templateUrl));
}));
Si carga a través de http y utiliza Chrome para sus pruebas, debe agregar compatibilidad con CORS en el servidor.