Usługa testowania w module zwrotów Angular nie jest zdefiniowana

128

Próbuję uruchomić domyślny test jednostki usług w moim projekcie (wzięty z projektu Angular Seed w serwisie GitHub), ale wciąż pojawia się błąd „moduł nie jest zdefiniowany”.

Czytałem, że może to mieć coś wspólnego z kolejnością plików JavaScript , do których istnieją odwołania , ale nie wydaje mi się, aby to działało, więc mam nadzieję, że ktoś z was może być w stanie pomóc.

Moja konfiguracja do testu wygląda następująco:

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 / filter.js ',
' public / services.js ',
JAŚMIN,
JASMINE_ADAPTER,
' public / javascripts / lib / angular -mocks. js ',
' test / unit / *. js '];

autoWatch = true;

browser = ['Chrome'];

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

Usługa wygląda następująco:

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

Test wygląda następująco:

'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');
    }));
  });
});

A błąd podczas uruchamiania testu przez testacular jest następujący:

ReferenceError: moduł nie jest zdefiniowany

Dofs
źródło
2
czy możesz gdzieś udostępnić swój projekt? Mogę pomóc. Czy próbowałeś włączyć poziom DEBUG dla testacular, aby zobaczyć, które pliki są faktycznie ładowane w oparciu o twoją konfigurację? Na razie podejrzaną częścią jest ten wzór: public / javascripts / lib / angular-.js - co powinno pasować?
pkozlowski.opensource
@JohnDoe Dzięki, że zadziałało. Jeśli dodasz odpowiedź, oznaczę ją jako rozwiązaną. Powodem było to, że śledziłem projekt seed, który zrobił to w ten sposób i który zadziałał. Nie wiem, czy to dlatego, że była to wcześniejsza wersja.
Dofs
@Dofs Czy "'public / javascripts / lib / angular-.js'," i "'public / controllers / .js'" są literówkami?
Ryan O'Neill
@ RyanO'Neill przepraszam, tak to była literówka.
Dofy

Odpowiedzi:

260

Brakuje pliku angular-mocks.js .

nieznany z nazwiska
źródło
8
Zauważ, że angular.modulei angular.mock.moduleto nie to samo. window.moduleFunkcja jest aliasem angular.mock.module. Zobacz tę odpowiedź, aby uzyskać więcej informacji.
Tim Schaub,
Jak mówi poprzedni komentarz, angular.module nie jest aliasem dla angular.mock.module.
Filippo De Luca,
7
Ta odpowiedź byłaby znacznie bardziej przydatna, gdyby zawierała jakąkolwiek radę dotyczącą sposobu udostępnienia wspomnianego pliku. Musiałem zainstalować Bower, a następnie NgMocks.
isherwood
4
Odpowiedź stanowi tylko część rozwiązania. To jest właściwie komentarz, a nie wyjaśnienie. Niektóre z poniższych odpowiedzi są znacznie bardziej szczegółowe.
Gerome Bochmann
1
Dla początkujących musisz dodać odniesienie do angular-mocksw karma.conf.jspliku i przeprowadzić testy przez Karmę, a nie Jasmine. W ten sposób, gdy Karma jest uruchomiona, pobiera angular-mocksrozszerzenia i wprowadza je do środowiska.
Łukasz
41

Miałem ten sam problem i zrozumiałem, dlaczego nie działa: javascript jasmine.js należy odwołać się PRZED plikiem angular-mocks.js. Rzeczywiście, angular-mocks.js sprawdza, czy Jasmine jest załadowana i tylko jeśli tak, doda funkcję modułu do okna.

Oto fragment kodu Angular Mocks:

(Edytuj po kilku komentarzach na temat `` hakowania '', które miałem poniżej: to tylko fragment kodu, to nie jest coś, co musisz pisać samemu, już tam jest!)

window.jasmine && (function(window) {

[...]

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

W skrócie: po prostu odwołaj się do pliku jasmine.js przed angular-mocks.js i gotowe.

Antoine Jaussoin
źródło
Można to również rozwiązać, upewniając się, że pliki javascript jasmine są ładowane przed makietami kątowymi. Czystsze rozwiązanie niż wprowadzanie hakerskich zmian, aby wszystko działało.
foomip
@foomip Kto zasugerował wprowadzenie hakerskich zmian?
Stephen
Zasadniczo wstawiłeś hack do swojej aplikacji, aby upewnić się, że ładuje się we właściwy sposób - i nie miałem na myśli hakowania w zły sposób (nie ma nic złego w sposobie, w jaki napisałeś ten fragment kodu), ale co się dzieje, gdy aktualizacja do jaśminu lub czegoś innego powoduje, że twój fragment zepsuje się lub nie działa zgodnie z oczekiwaniami? To mogło się zdarzyć lub nie mogło się zdarzyć, ale w twoim kodzie jest teraz obciążenie, którego można by uniknąć, nie sądzisz?
foomip
@foomip: Nie jestem pewien, do czego się odnosisz, ale jeśli chodzi o mój kod powyżej, to nie został napisany przeze mnie, cytuję go tylko, aby wyjaśnić problem. Kod jest częścią makiet kątowych. Poprawka polega po prostu na odwołaniu się do jednego pliku przed drugim.
Antoine Jaussoin
36

Ta window.modulefunkcja znajduje się w angular-mocks.js i jest skrótem dla angular.mock.module. Jak wspomniano w dokumentacji , modulefunkcja działa tylko z Jasmine.

Używając Testacular , załaduje się następujący przykładowy plik konfiguracyjny 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'];

I, jak sugerowano w innym miejscu, możesz uruchomić Testacular z rejestrowaniem debugowania, aby zobaczyć, jakie skrypty są ładowane (możesz również zobaczyć to samo w inspektorze):

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

W angular.mock.injectdocs to ładny kompletny przykład.

Tim Schaub
źródło
Być może warto zauważyć, że moduleteraz działa również z mokką
Robin-Hoodie
11

W naszych testach jednostkowych używamy „modułu” bez „kątowego” i działa dobrze.

CoffeeScript:

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

który kompiluje się do

JavaScript:

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

Jedyny przypadek, kiedy widzę coś podobnego do opisanego przez ciebie błędu, to sytuacja, gdy w pliku testacular.conf.js plik angular-mocks.js nie jest wymieniony w sekcji plików przed próbą użycia parametru „module”. Jeśli po testach umieszczę go na liście „plików”, którą otrzymuję

ReferenceError: Can't find variable: module

(Nasze testy są przeprowadzane przez PhantomJS)

Ryan O'Neill
źródło
2
Podsumowując, kanciaste makiety są wymagane.
Adrien,
3

Umieściłem angular-mocks.js w mojej konfiguracji karmy, ale nadal otrzymywałem błąd. Okazuje się, że kolejność jest ważna w tablicy plików. (duh) Podobnie jak w nagłówku dokumentu html, jeśli skrypt wywołuje angular przed jego zdefiniowaniem i pojawia się błąd. Musiałem więc po prostu dołączyć plik app.js po angular.js i angular-mocks.js.

Erik
źródło
0

Jeśli używasz Yeoman i jego generatora kątów, prawdopodobnie otrzymujesz ten błąd. Zwłaszcza gdy robisz samouczek (._.)
Naprawiłem to, kopiując plik angular-mocks.js z katalogu bower_components / angular-mocks do katalogu test / mock. Oczywiście musisz mieć pewność, że Twój plik karma.conf.js jest poprawnie skonfigurowany.
Pozdrowienia!

alxU
źródło
0

Miałem ten sam problem, kiedy robiłem coś takiego var module = angular.module('my',[]). Musiałem się upewnić, że jest otoczony przez IIFE

Jackie
źródło