Le service de test dans le module de retours angulaires n'est pas défini

127

J'essaie d'exécuter le test d'unité de service par défaut dans mon projet (tiré du projet Angular Seed sur GitHub), mais j'obtiens toujours l'erreur "module n'est pas défini".

J'ai lu que cela pourrait être lié à l'ordre des fichiers JavaScript référencés , mais je n'arrive pas à le faire fonctionner, alors j'espère que l'un de vous pourra vous aider.

Ma configuration pour le test ressemble à ceci:

basePath = '../';

files = [
'public / javascripts / lib / jquery-1.8.2.js',
'public / javascripts / lib / angular.js',
'public / javascripts / lib / angular- .js',
'public / app.js ',
' public / controllers /
.js ',
' public / directives.js ',
' public / filters.js ',
' public / services.js ',
JASMINE,
JASMINE_ADAPTER,
' public / javascripts / lib / angular-mocks. js ',
' test / unité / *. js '];

autoWatch = vrai;

navigateurs = ['Chrome'];

junitReporter = {outputFile: 'test_out / unit.xml', suite: 'unit'};

Le service ressemble à ce qui suit:

angular.module('myApp.services', []).
  value('version', '0.1');

Le test ressemble à ceci:

'use strict';

describe('service', function() {
  beforeEach(module('myApp.services'));


  describe('version', function() {
    it('should return current version', inject(function(version) {
      expect(version).toEqual('0.1');
    }));
  });
});

Et l'erreur lors de l'exécution du test via testacular est la suivante:

ReferenceError: le module n'est pas défini

DOF
la source
2
pouvez-vous partager votre projet quelque part? Je pourrais peut-être aider. Avez-vous essayé d'activer le niveau DEBUG pour que testacular puisse voir quels fichiers sont réellement chargés en fonction de votre configuration? Pour l'instant, la partie suspecte est ce motif: public / javascripts / lib / angular-.js - que doit-il correspondre?
pkozlowski.opensource
@JohnDoe Merci qui a fonctionné. Si vous ajoutez une réponse, je la marquerai comme résolue. La raison était que je suivais le projet d'amorçage, qui l'a fait de cette façon et qui a fonctionné. Je ne sais pas si c'est parce que c'était une version antérieure.
Dofs du
@Dofs Les fautes de frappe "" public / javascripts / lib / angular-.js "," et "" public / controllers / .js ""?
Ryan O'Neill
@ RyanO'Neill désolé, oui c'était une faute de frappe.
Dofs

Réponses:

260

Il vous manque le fichier angular-mocks.js .

John Doe
la source
8
Notez que angular.moduleet neangular.mock.module sont pas les mêmes. La window.modulefonction est un alias pour angular.mock.module. Voir cette réponse pour plus.
Tim Schaub
Comme le dit le commentaire précédent, angular.module n'est pas un alias pour angular.mock.module.
Filippo De Luca
7
Cette réponse serait beaucoup plus utile si elle offrait des conseils sur la manière de fournir ledit fichier. J'avais besoin d'installer Bower, puis NgMocks.
isherwood
4
La réponse n'apporte qu'une partie de la solution. C'est en fait un commentaire et non une explication. Certaines des réponses ci-dessous sont beaucoup plus détaillées.
Gerome Bochmann
1
Pour les débutants, vous devez ajouter une référence à angular-mocksdans le karma.conf.jsfichier et exécuter les tests via Karma, pas Jasmine. De cette façon, lorsque Karma est exécuté, il récupère les angular-mocksextensions et les incorpore dans l'environnement.
Luc
41

J'ai eu le même problème, et j'ai compris pourquoi cela ne fonctionnait pas: le javascript jasmine.js doit être référencé AVANT le fichier angular-mocks.js. En effet, le angular-mocks.js vérifie si Jasmine est chargé, et seulement si c'est le cas, il ajoutera la fonction du module à la fenêtre.

Voici un extrait du code Angular Mocks:

(Modifiez après les quelques commentaires sur le 'piratage' que j'ai eu ci-dessous: ce n'est qu'un extrait du code, ce n'est pas quelque chose que vous devez écrire vous-même, c'est déjà là!)

window.jasmine && (function(window) {

[...]

  window.module = angular.mock.module = function() {
    var moduleFns = Array.prototype.slice.call(arguments, 0);
    return isSpecRunning() ? workFn() : workFn;
    /////////////////////
    [...]
  };

En un mot: référencez simplement votre jasmine.js avant angular-mocks.js et c'est parti.

Antoine Jaussoin
la source
Cela peut également être résolu en s'assurant que les fichiers javascript jasmin sont chargés avant angular-mocks. Une solution plus propre que de faire des changements hacky pour faire fonctionner les choses.
foomip
@foomip Qui a suggéré de faire des changements hacky?
Stephen
Vous avez essentiellement inséré un piratage dans votre application pour vous assurer que les choses se chargent de la bonne façon - et je ne voulais pas dire pirater d'une mauvaise manière (il n'y a rien de mal dans la façon dont vous avez écrit cet extrait de code) mais que se passe-t-il quand un mettre à jour vers jasmine ou autre chose provoque la rupture de cet extrait de code ou ne fonctionne plus comme prévu? Cela pourrait ou ne pourrait pas arriver, mais c'est une responsabilité dans votre code qui pourrait être évitée, n'est-ce pas?
foomip
@foomip: Je ne suis pas sûr de ce à quoi vous faites référence, mais s'il s'agit de mon code ci-dessus, cela n'a pas été écrit par moi, je le cite simplement pour expliquer le problème. Le code fait partie de angular-mocks. Le correctif consiste simplement à référencer un fichier avant l'autre.
Antoine Jaussoin
36

La window.modulefonction vient dans angular-mocks.js et est un raccourci pour angular.mock.module. Comme mentionné dans la documentation , la modulefonction ne fonctionne qu'avec Jasmine.

En utilisant Testacular , l'exemple de fichier de configuration suivant se chargera angular-mocks.js.

/** example testacular.conf.js */

basePath = '../';
files = [
  JASMINE,
  JASMINE_ADAPTER,
  'path/to/angular.js',
  'path/to/angular-mocks.js',   // for angular.mock.module and inject.
  'src/js/**/*.js',             // application sources
  'test/unit/**/*.spec.js'      // specs
];
autoWatch = true;
browsers = ['Chrome'];

Et, comme suggéré ailleurs, vous pouvez exécuter Testacular avec la journalisation du débogage pour voir quels scripts sont chargés (vous pouvez également voir la même chose dans l'inspecteur):

testacular --log-level debug start config/testacular.conf.js

Les angular.mock.injectdocuments incluent un exemple assez complet.

Tim Schaub
la source
Il convient peut-être de noter que modulemaintenant fonctionne également avec le moka
Robin-Hoodie
11

Nous utilisons «module» sans «angulaire» dans nos tests unitaires et cela fonctionne très bien.

CoffeeScript:

describe 'DiscussionServicesSpec', ->
    beforeEach module 'DiscussionServices'
    beforeEach inject ... etc.

qui se compile en

JavaScript:

describe('DiscussionServices', function() {
    beforeEach(module('DiscussionServices'));
    beforeEach(inject(function ... etc.

La seule fois où je vois quelque chose comme l'erreur que vous avez décrite, c'est si dans le fichier testacular.conf.js le fichier angular-mocks.js n'est pas répertorié dans la section des fichiers avant les spécifications essayant d'utiliser le 'module'. Si je le mets après mes tests dans la liste des 'fichiers', j'obtiens

ReferenceError: Can't find variable: module

(Nos tests sont exécutés via PhantomJS)

Ryan O'Neill
la source
2
La chose à conclure est que les simulations angulaires sont une exigence.
Adrien
3

J'avais inclus angular-mocks.js dans ma configuration de karma, mais j'obtenais toujours l'erreur. Il s'avère que l'ordre est important dans le tableau des fichiers. (duh) Tout comme dans la tête d'un doc html, si un script appelle angular avant qu'il ne soit défini, une erreur se produit. Je devais donc juste inclure mon app.js après angular.js et angular-mocks.js.

Erik
la source
0

Si vous utilisez Yeoman et son générateur angulaire, vous obtenez probablement cette erreur. Surtout quand vous faites le Tutoriel (._.)
Je l'ai corrigé, en copiant le fichier angular-mocks.js, du répertoire bower_components / angular-mocks vers le répertoire test / mock. Bien sûr, vous devez être sûr que votre fichier karma.conf.js est correctement configuré.
Salutations!

alxU
la source
0

J'ai eu ce même problème quand je faisais quelque chose comme var module = angular.module('my',[]). J'avais besoin de m'assurer qu'il était entouré de IIFE

Jackie
la source