Reputation: 3199
I am trying to unit test an html template that has variables in paragraph, anchor tags, and {{header.title || translate}}
however no matter what posts I have tried it does not seem to work. I get the retrieved HTML template and when it is compiled it is still the same. In the template I still see {{user}}
for example. It seems none of them are actually being compiled.
Current Template Output:
<h1>{{header.title | translate}}</h1>
<h2>{{homeCtrl.name}}</h2>
Expected Output:
<h1>Cake Blogger</h1>
<h2>Alexandria</h2>
Test Suite:
(function() {
'use strict';
describe('home.tpl.html', function() {
var scope, controller, createController, template, element, rootScope;
beforeEach(module('Templates'));
beforeEach(module('mainApp'));
/**
@name: home.tpl.html
@description: Inject and set test related objects
@param {Service} rootScope - Used to get the language
@param {Compiler} $templateCache - Holding the compiled template
@param {Injector} $compile - Compiles an HTML string or DOM
*/
beforeEach(inject(
function(_$controller_, _$rootScope_, $templateCache, $compile) {
scope = _$rootScope_.$new();
createController = function() {
return _$controller_('homeCtrl', {
'$scope': scope
});
};
controller = createController();
rootScope = _$rootScope_;
template = $templateCache.get('home.tpl.html');
element = $compile(template)(rootScope);
// var ctrl = element.controller('homeCtrl');
rootScope.$digest();
console.log("home page", element);
}));
/**
@name: Describe Block - home.tpl.html
@description: Test cases related to home.tpl.html
*/
describe('home.tpl.html tests', function() {
fit('should have "Alexandria"', function() {
expect(element.html()).toContain("Alexandria");
});
});
});
})();
Karma File:
files: ['list of files'],
port: 8080,
browsers: [
'PhantomJS'
],
plugins: [
'karma-phantomjs-launcher',
'karma-jasmine',
'karma-ng-html2js-preprocessor',
],
preprocessors: {
'app/**/*.tpl.html': 'html2js'
},
ngHtml2JsPreprocessor: {
'moduleName': 'Templates',
'stripPrefix': 'app/'
}
package.json
{
"name": "",
"private": true,
"devDependencies": {
"autoprefixer-core": "^5.2.1",
"grunt": "^0.4.5",
"grunt-angular-templates": "^0.5.7",
"grunt-concurrent": "^1.0.0",
"grunt-contrib-clean": "^0.6.0",
"grunt-contrib-compass": "^1.0.0",
"grunt-contrib-concat": "^0.5.0",
"grunt-contrib-connect": "^0.9.0",
"grunt-contrib-copy": "^0.7.0",
"grunt-contrib-cssmin": "^0.12.0",
"grunt-contrib-htmlmin": "^0.4.0",
"grunt-contrib-imagemin": "^1.0.0",
"grunt-contrib-jshint": "^0.11.0",
"grunt-contrib-uglify": "^0.7.0",
"grunt-contrib-watch": "^0.6.1",
"grunt-filerev": "^2.1.2",
"grunt-google-cdn": "^0.4.3",
"grunt-jscs": "^1.8.0",
"grunt-karma": "*",
"grunt-modernizr": "^1.0.2",
"grunt-newer": "^1.1.0",
"grunt-ng-annotate": "^0.9.2",
"grunt-ng-constant": "^2.0.1",
"grunt-postcss": "^0.5.5",
"grunt-svgmin": "^2.0.0",
"grunt-usemin": "^3.0.0",
"grunt-wiredep": "^2.0.0",
"jasmine-core": "^2.4.1",
"jit-grunt": "^0.9.1",
"jshint-stylish": "^1.0.0",
"karma": "^0.13.22",
"karma-coverage": "^0.5.5",
"karma-fixture": "^0.2.6",
"karma-jasmine": "*",
"karma-json-fixtures-preprocessor": "0.0.6",
"karma-json-preprocessor": "^0.3.3",
"karma-junit-reporter": "^1.2.0",
"karma-ng-html2js-preprocessor": "~0.1.0",
"karma-phantomjs-launcher": "*",
"phantomjs": "^2.1.7",
"time-grunt": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "grunt test"
},
"dependencies": {}
}
According to posts I have read such as this plunker from a post plunker example, this should be working correctly. I am thinking perhaps the controller is not binding to the scope so that when $digest
runs the template cannot find the controller maybe.
Helpful Information:
rootscope.$digest()
I also tried it as scope.$digest()
, I also tried using $apply()
.ngHtml2JsPreprocessor
TemplateCache
$compile
Links viewed:
The template returns but the angular in the template is never compiled. Always seeing {{homeCtrl.name}}
instead of Alexandria
.
Update 1.1
I am thinking perhaps since the translate {{header.title | translate}}
is not working that maybe angular-translate
(module: pascalprecht.translate
) is not actually working correctly and is then causing the controller to also fail binding. Will continue investigation.
Upvotes: 3
Views: 748
Reputation: 56
After injecting angular-translate
the | translate
filter just works and yields expected translated value after $compile. See this plunker as an example:
http://plnkr.co/edit/j8rbnMI067YntllwTcGi?p=preview
One possible reason that leads to your issue is timing - suppose you have big translate array / json and it takes a while to load, but Jasmine testing already starts and finishes before they are fully loaded and ready. Then Jasmine will see un-translated string during tests.
Updated 2017-06-30
After a few experiments, I can confirm that any async json loader, whether it's .useStaticFilesLoader
or $.getJSON()
, will not be executed before jasmine. See http://plnkr.co/edit/nreUd52iqOVvwLPMNtJA?p=preview as an example, the static loader works fine for page view but fails unit test.
One possible way to go is to ditch .useStaticFilesLoader
completely. Instead, we can use grunt-replace
to inject the translations during the build process. Example grunt task:
// replace string with json
replace: {
dist: {
options: {
patterns: [
{
match: /\"JSONEN\"/,
replacement: '<%= grunt.file.read("app/resources/en.json") %>'
}
]
},
files: [
{expand: true, flatten: true, src: ['app/scripts/app.js'], dest: 'public/'}
]
}
}
Upvotes: 1