Tests unitaires de la sortie de $sce.trustAsHtml Angulaire
Je suis en train d'écrire un RESTE d'application dans Angulaire et je veux écrire des tests unitaires pour elle (bien sûr!). J'ai un contrôleur qui permet d'obtenir une liste de messages de blog à partir d'un service REST json et met l'résumés dans le $champ d'application, afin que je puisse les afficher dans la vue.
Au premier abord, les messages de blog ont été simplement les afficher en tant que texte ie <p>Blog body</p>
, plutôt que de rendu comme HTML analysée, jusqu'à ce que j'ai découvert que vous pouvez utiliser ng-bind-html en collaboration avec le $sce service. Cela fonctionne à présent bien en termes d'afficher les messages de blog correctement.
Le problème se pose lorsque les tests unitaires. Je suis en train de simuler une réponse json avec le code HTML, puis test que mon contrôleur est correctement traiter avec le HTML. Voici mon code:
Contrôleur
.controller( 'HomeCtrl', function HomeController( $scope, $http, $sce ) {
$scope.posts = {};
$http.get('../drupal/node.json').success(function (data) {
var posts;
posts = data.list;
for(var i = 0; i < posts.length; i ++) {
posts[i].previewText = $sce.trustAsHtml(posts[i].body.summary);
posts[i].created = posts[i].created + '000'; //add milliseconds so it can be properly formatted
}
$scope.posts = posts;
});
})
de test de l'unité
describe('HomeCtrl', function() {
var $httpBackend, $rootScope, $sce, createController;
beforeEach(inject(function ($injector) {
//Set up the mock http service responses
$httpBackend = $injector.get('$httpBackend');
//Get hold of a scope (i.e. the root scope)
$rootScope = $injector.get('$rootScope');
//The $controller service is used to create instances of controllers
var $controller = $injector.get('$controller');
$sce = $injector.get('$sce');
createController = function() {
return $controller('HomeCtrl', {
'$scope': $rootScope
});
};
}));
it('should get a list of blog posts', function() {
var rawResponse = {
"list": [
{
"body": {
"value": "\u003Cp\u003EPost body.\u003C\/p\u003E\n",
"summary": "\u003Cp\u003ESummary.\u003C\/p\u003E\n"
},
"created": "1388415860"
}
]};
var processedResponse = [{
"body": {
"value": "\u003Cp\u003EPost body.\u003C\/p\u003E\n",
"summary": "\u003Cp\u003ESummary.\u003C\/p\u003E\n"
},
"created": "1388415860000",
previewText: $sce.trustAsHtml("\u003Cp\u003ESummary.\u003C\/p\u003E\n")
}];
$httpBackend.when('GET', '../drupal/node.json').respond(rawResponse);
$httpBackend.expectGET("../drupal/node.json").respond(rawResponse);
var homeCtrl = createController();
expect(homeCtrl).toBeTruthy();
$httpBackend.flush();
expect($rootScope.posts).toEqual(processedResponse);
});
});
Quand je lance le biais de la Karma lanceur de test, j'obtiens la réponse suivante:
Chrome 31.0.1650 (Windows) home section HomeCtrl should get a list of blog posts FAILED
Expected [ { body : { value : '<p>Post body.</p>
', summary : '<p>Summary.</p>
' }, created : '1388415860000', previewText : { $$unwrapTrustedValue : Function } } ] to equal [ { body
: { value : '<p>Post body.</p>
', summary : '<p>Summary.</p>
' }, created : '1388415860000', previewText : { $$unwrapTrustedValue : Function } } ].
Je soupçonne que le problème est dû au fait que $sce.trustAsHtml
retourne un objet contenant une fonction, plutôt qu'une chaîne de caractères.
Ma question est, tout d'abord, suis-je aborder ce problème dans le bon sens?
Deuxièmement, dans l'affirmative, comment dois-je aller sur l'évaluation de la sortie de $sce.trustAsHtml
?
Vous devez vous connecter pour publier un commentaire.
Depuis la réponse donnée par michael-bromley ne fonctionne pas pour moi, je tiens à souligner une autre solution. Dans mon cas, j'ai été en utilisant un filtre qui encapsule chaque occurrence d'une chaîne dans une autre chaîne avec un span qui a une classe de 'évidence'. En d'autres termes, je veux dire d'être souligné. Voici le code:
J'utilise le $sce service de confiance de la valeur HTML. Pour tester cela, j'ai besoin d'utiliser le $$unwrapTrustedValue fonction de la valeur qui en résulte pour obtenir mon test de travail:
Mise à JOUR:
Comme @gugol aimablement fait remarquer, il est préférable de ne pas utiliser Angulaire méthodes internes tels que $$unwrapTrustedValue. Une meilleure approche est d'utiliser le public getTrustedHtml méthode sur l' $sce service. Comme:
expect($sce.getTrustedHtml(result).toEqual('this <span class="highlighted">str</span> contains a <span class="highlighted">str</span> that will be a highlighted <span class="highlighted">str</span>.');
$sce.trustAsHtml()
(qui renvoie un objet) au lieu de$sce.getTrustedHtml()
. Merci pour cette réponse, cela a fonctionné pour moi aussi.Vous devez désactiver $sec à l'aide de son fournisseur avant chaque test.
Lorsque $sce est désactivé tous les $sce.confiance* les méthodes de retour juste valeur d'origine au lieu d'une fonction wrapper.
Dans votre exemple il suffit de faire ceci:
J'ai découvert que vous pouvez utiliser
$sce.getTrusted
qui va renvoyer la valeur initialement transmis à$sce.trustAsHtml
, dans ce cas, une chaîne de caractères contenant du code HTML, que vous pouvez ensuite tester l'égalité de la manière habituelle.Donc mon test ressemble maintenant à ceci:
getTrustedHtml
lors de l'obtention de votre valeur d'origine dans le test. docs.angularjs.org/api/ng/service/$sce#getTrustedHtmlUne autre option est d'utiliser le getTrustedHtml() pour obtenir le code html de la chaîne de valeur de $$unwrapTrustedValue.