web-dev-qa-db-fra.com

Mocking des dépendances du module AngularJS dans les tests unitaires Jasmine

J'essaie de tester un peu le code du contrôleur dans un module qui considère les autres modules comme des dépendances, mais je n'ai pas réussi à comprendre comment les imiter correctement.

J'utilise Jasmine Framework et j'effectue mes tests avec Karma (Testacular).

Code du module

var app = angular.module('events', ['af.widgets', 'angular-table']);

app.controller('eventsCtrl', function([dependencies]){
    $scope.events = [];
    ...
});

code de spécification

describe('events module', function(){
    var $scope,
        ctrl;

    beforeEach(function(){
        angular.mock.module('af.widgets', []);
        angular.mock.module('angular-table', []);
        module('events', ['af.widgets', 'angular-table']);
    });

    beforeEach(inject(function($rootScope, $controller){
        $scope = $rootScope.new();
        ctrl = $controller('NameCtrl', {
            $scope: $scope,
        });
    }));

    it('should have an empty events array', function(){
        expect($scope.events).toBe([]);
    })
});

L'erreur que je reçois est que Karma n'est "pas de module af.widgets", donc évidemment je ne me moque pas des dépendances de module. Des allusions?

71
fscof

Si vous voulez simuler un module qui déclare un ou plusieurs services, j'ai utilisé ce code:

beforeEach(function(){
    module('moduleToMock');
    module(function ($provide) {
        $provide.value('yourService', serviceMock);
    });
});

Ceci est utile si le service que vous souhaitez simuler est également un service que vous souhaitez tester à l’unité (dans une autre description jasmine). La solution proposée par fscof est correcte, mais vous ne pouvez pas créer de test unitaire pour le angular-table module.

65
Davide Icardi

Voici ce que j'ai compris:

Je ne chargeais aucun module 'table angulaire' dans mon fichier karma.conf.js, d'où l'erreur. C'était intentionnel au début car je voulais tester le module 'événements' sans le module table réel.

J'ai pu facilement simuler le module 'angular-table' en créant un nouveau fichier dans mon dossier de test appelé 'mocks/angular-table.js' et en ajoutant le code suivant:

/mocks/angular-table.js

'use-strict';
angular.module('angular-table', []);

J'ai ajouté ce fichier à mon fichier karma.conf.js, ainsi que le module réel "événements" que je voulais tester:

karma.conf.js

...
files = [
    JASMINE,
    JASMINE_ADAPTER,
    'scripts/libs/angular.js',
    'scripts/libs/angular-mocks.js',
    'scripts/events.js', // this is the real module.
    'scripts/mocks/*.js', //loads all custom mocks.
    'scripts/specs/*.spec.js' // loads my spec file.
] 
...

Enfin, dans mon fichier de spécification, j'ai pu ajouter les deux modules en les appelant séparément dans un bloc beforeEach:

specs/events.spec.js

beforeEach(function(){
    module('angular-table');
    module('events');
});

J'ai eu l'idée de structurer mes fichiers de cette manière à partir de this post

46
fscof

J'ai récemment publié ngImprovedTesting qui devrait faciliter les tests fictifs de manière angulaire.

Dans votre cas, utilisez simplement les éléments suivants dans votre test Jasmine:

beforeEach(ModuleBuilder.forModule('events').serviceWithMocks('eventsCtrl').build());

Pour plus d'informations sur ngImprovedTesting, consultez son article de blog d'introduction: http://blog.jdriven.com/2014/07/ng-improved-testing-mock-testing-for-angularjs-made-easy/ =

3
Emil van Galen