Test $portée dans AngularJs contrôleur avec dépendance sur filtre $
Je suis passé par quelques tutoriels et des exemples de base, mais je vais avoir un moment difficile de l'écriture de tests unitaires pour mon contrôleur. J'ai vu des extraits de code de l'instanciation de contrôleurs et de laisser angulaire d'injecter de l' $rootScope
objet qui à son tour est utilisé pour créer un nouveau scope
objet pour le contrôleur. Mais je ne peux pas comprendre pourquoi ctrl.$scope
? est pas défini:
describe('EmployeeCtrl', function () {
var scope, ctrl, $httpBackend;
beforeEach(inject(function (_$httpBackend_, $rootScope, $controller, $filter) {
$httpBackend = _$httpBackend_;
scope = $rootScope.$new();
ctrl = $controller('EmployeeCtrl', { $scope: scope});
expect(ctrl).not.toBeUndefined();
expect(scope).not.toBeUndefined(); //<-- PASS!
expect(ctrl.$scope).not.toBeUndefined(); //<-- FAIL!
}));
});
J'ai fini par utiliser la scope
variable au lieu de ctrl.$scope
mais sur mon premier essai, je ne pouvais pas comprendre comment le test de l'unité d'un variable de fonction à l'intérieur de mon contrôleur:
Contrôleur:
function EmployeeCtrl($scope, $http, $filter, Employee) {
var searchMatch = function (haystack, needle) {
return false;
}
}
Brisé l'unité de test:
it('should search ', function () {
expect(ctrl.searchMatch('numbers','one')).toBe(false);
});
C'est ce que je reçois
TypeError: Object # n'a pas de méthode 'searchMatch'
Comment pouvez-vous tester cette fonction? Comme une solution de contournement que j'ai déplacé ma méthode de dollars à portée, donc j'ai pu tester pour scope.searchMatch
mais je me demandais si c'est la seule façon.
Enfin, sur mes tests est semble $filter
est undefined, comment avez-vous l'injecter? J'ai essayé cela, mais n'a pas fonctionné:
ctrl = $controller('EmployeeCtrl', { $scope: scope, $filter: $filter });
Grâce
Mise à jour:
La méthode mentionnée ci-dessus à injecter $filtre fonctionne très bien.
- mon jasmin test se brise sur les injecter de la méthode. Il n'est pas trouvé. Ce qui me manque. angulaire n'est pas nulle. J'ai un test qui passe, qui vérifie si elle est chargée.
Vous devez vous connecter pour publier un commentaire.
Ma compréhension est que, dans Angularjs, vous passez un objet de l'étendue du contrôleur lorsque le démarrage de l'application et le contrôleur de nature à modifier la portée. Le contrôleur n'est pas appelé plus.
Ce qu'un contrôleur est vraiment en train de faire, en Angularjs, est en cours d'initialisation du champ d'application: le contrôleur ne lance qu'une seule fois.
Si vous comprenez cela, vous vous rendez compte que le fait de poser pour le contrôleur de la portée comme ceci:
n'a pas de sens.
(D'ailleurs, l'une des choses que je n'aime pas Angulaire est le nom qu'ils ont choisi. Si ce qu'est un "contrôleur" est en train de faire est d'initialiser le champ d'application, alors il n'est pas vraiment un contrôleur. Il y a beaucoup de cela dans l'Angulaire de l'API).
Je pense que le " bon "chemin pour le test d'un "contrôleur" est la création d'un nouveau champ d'application à partir de zéro dans un Jasmin beforeEach clause et en utilisant le "contrôleur" pour initialisation une nouvelle portée comme ceci::
Et le test de la nouvelle portée a les propriétés:
En d'autres termes, vous ne testez pas le contrôleur; vous de tester la portée que le contrôleur a créé.
Donc, vous le faites à droite.
Voici un autre modèle qui pourrait être plus simple à suivre:
Vous pouvez utiliser ce même modèle pour définir les valeurs de $lieu $et fenêtre ainsi que d'autres.
Il y a seulement deux possibilités:
Ajouter
searchMatch
à la portée (comme vous l'avez mentionné) ouRetour de la
searchMatch
fonction:S'il doit vraiment rester privé, alors vous aurez à tester les fonctionnalités qui l'utilisent.
Pour obtenir le
$filter
, vous pouvez essayer ce qui suit: