web-dev-qa-db-fra.com

AngularJS - Comment tester si une fonction est appelée depuis une autre fonction?

J'essaie de commencer avec le karma-jasmin et je me demande pourquoi ce test échoue:

it("should call fakeFunction", function() {
    spyOn(controller, 'addNew');
    spyOn(controller, 'fakeFunction');
    controller.addNew();
    expect(controller.fakeFunction).toHaveBeenCalled();
});

Dans mon contrôleur que j'ai précédemment configuré pour ce test, j'ai les éléments suivants:

function addNew() {
    fakeFunction(3);
}

function fakeFunction(number) {
    return number;
}

addNew et fakeFunction sont exposés en utilisant:

vm.addNew = addNew;
vm.fakeFunction = fakeFunction;

Le test échoue cependant avec les éléments suivants:

Expected spy fakeFunction to have been called.

Je peux réussir le test si j'appelle la fonction depuis mon test. J'espérais cependant pouvoir tester si fakeFunction était appelé par une autre fonction. Quelle est la bonne façon d'y parvenir?

Mettre à jour:

//test.js

beforeEach(function() {

    module("app");

    inject(function(_$rootScope_, $controller) {

        $scope = _$rootScope_.$new();
        controller = $controller("CreateInvoiceController", {$scope: $scope});

    });

});

Si je teste quelque chose comme:

it('should say hello', function() {
    expect(controller.message).toBe('Hello');
});

Le test réussit si je mets ce qui suit dans mon contrôleur:

var vm = this;
vm.message = 'Hello';

Je veux juste savoir comment tester si une fonction publique a été appelée à partir d'une autre fonction.

11
Raphael Rafatpanah

Votre méthode addNew appelle fakeFunction. Cependant, il n'appelle pas controller.fakeFunction, quelle est votre attente.

Vous devrez modifier votre code pour utiliser votre contrôleur, plutôt que ces fonctions indépendantes.

EDIT : Vous devez également ne pas espionner votre fonction addNew. Cela provoque le remplacement de la fonction par un espion. L'autre alternative est de le changer en:

spyOn(controller, 'addNew').and.callThrough()
10
Vadim

Je viens de rencontrer ce problème moi-même. La réponse précédente de @Vadim a les bons principes mais je ne pense pas que tout était très clair. Dans mon cas, j'essaie d'appeler une fonction publique sur un service à partir d'une autre fonction. Voici les extraits pertinents:

Un service:

angular.module('myApp').factory('myService', function() {

    function doSomething() {
      service.publicMethod();
    }

    function publicMethod(){
      // Do stuff
    }

    var service = {
      publicMethod: publicMethod
    };

    return service;
});

Tester:

it('calls the public method when doing something', function(){
  spyOn(service, 'publicMethod');

  // Run stuff to trigger doSomething()

  expect(service.publicMethod).toHaveBeenCalled();
});

La clé ici est que la fonction en cours de test doit appeler la même référence que la fonction publique qui est espionnée.

8
Alex White