2015-01-28 8 views
27

Mam plik o nazwie test/helper.js, którego używam do uruchamiania testów Mocha w moich aplikacjach Node.js. Moja struktura wygląda testy:W jaki sposób zmusić Mocha do załadowania pliku helper.js, który definiuje globalne przechwyty lub narzędzia?

test/ 
test/helper.js # global before/after 
test/api/sometest.spec.js 
test/models/somemodel.spec.js 
... more here 

Plik helper.js musi być załadowany, ponieważ zawiera globalne haki dla mojego testu pakietu. Kiedy uruchamiam Mocha wykonać cały zestaw testów tak:

mocha --recursive test/ 

plik helper.js jest ładowany przed moich testów i mój hak before zostanie wykonany zgodnie z oczekiwaniami.

Jednak po uruchomieniu tylko jednego testu, helper.js nie zostanie załadowany przed testem. Jest to, jak go uruchomić:

mocha test/api/sometest.spec.js 

nr globalnej before nazwie, nawet console.log('I WAS HERE');.

Więc jak mogę uzyskać Mocha do zawsze załadować mój plik helper.js?

+0

z pytaniem edytowany, odpowiedź teraz czyni mniej sensu. – Zlatko

Odpowiedz

20

Mocha nie ma żadnego pojęcia specjalnego pliku o nazwie helper.js, który wczytałby przed innymi plikami.

To, co próbujesz zrobić, działa po uruchomieniu mocha --recursive z powodu kolejności, w której Mocha stanie się, aby załadować twoje pliki. Ponieważ helper.js jest o jeden poziom wyżej niż inne pliki, jest ładowany jako pierwszy. Po określeniu pojedynczego pliku do Mocha, wtedy Mocha po prostu ładuje ten plik i, jak odkryłeś, twój plik helper.js nie jest w ogóle załadowany.

Co chcesz zrobić, to załadować plik taki, że ustawi haki najwyższego poziomu ("globalne") (np. before, after itd.). Opcje:

  1. Możesz użyć Mocha programmatically i podać pliki w żądanej kolejności.

  2. Możesz wymusić na użytkowniku, aby zawsze podawać plik pomocnika w wierszu poleceń najpierw przed podaniem listy innych plików. (Nie zrobiłbym tego, ale jest to możliwe.)

  3. Inną opcją jest uporządkowanie apartamentu, tak jak to opisano w artykule this answer. Zasadniczo masz jeden plik "najwyższego poziomu", który ładuje do niego resztę pakietu. Dzięki tej metodzie stracisz możliwość uruchamiania Mocha na poszczególnych plikach, ale możesz użyć opcji --grep, aby wybrać uruchamiany program.

Ty nie może należy wybrać opcję -r. Ładuje moduł przed uruchomieniem pakietu, ale niestety załadowany moduł nie ma dostępu do żadnego interfejsu testowego, który Mocha udostępnia do testów, więc nie może ustawić haków.

+0

Czy byłoby możliwe wykorzystanie kolejności ładowania plików testowych, tak żebym miał tylko jeden plik w folderze 'test' (z globalnymi hakami itp.), Np.' Helper.js' i wszystkie inne pliki testowe wewnątrz podkatalogu, tj. "jednostka"? (** Aktualizacja: ** * Ach, wydaje się, że odpowiedź, której szukam, jest już częścią pytania -> tak.:)). –

+0

Co sugerujesz, to druga opcja w mojej odpowiedzi. Nie powtórzyłem, co się dzieje, gdy uruchamiasz 'mocha' bez argumentów (które OP zna i rozumie). Właśnie wspomniałem, jak możesz sprawić, żeby działało, jeśli chcesz uruchomić tylko jeden określony plik: 'mocha test/helper.js [cokolwiek innego pliku]'. – Louis

+0

Dzięki, ale dlaczego miałbym załadować plik helper.js w ogóle? Myślałem, że mocha szuka tylko plików, które mają "spec" gdzieś w nazwie? – Zlatko

10

Co mogę zrobić, to utworzyć plik test/test_helper.js, które wywozi wszystkich pomocników tworzę:

// test/test_helper.js  
module.exports = { 
    MyHelper: require('./helpers/MyHelper') 
} 

Potem require pomocnika na każdym teście muszę z niego korzystać:

// test/spec/MySpec.js 
var helper = require('../test_helper'); 

// Or if you need just "MyHelper" 
var myHelper = require('../test_helper').MyHelper; 

describe('MySpec', function() { 
    // Tests here... 
}); 

I preferuj powyższe podejście, ponieważ jest łatwe do zrozumienia i elastyczne. Możesz zobaczyć to w akcji tutaj w mojej wersji demonstracyjnej: https://github.com/paulredmond/karma-browserify-demo/tree/master/test

9

Po pierwsze, zdecydowanie użyłbym mocha.opts, dzięki czemu nie musisz uwzględniać opcji, które chcesz za każdym razem. Jak wskazano, jedną z opcji jest użycie --grep, ale nie jestem wielkim fanem tego osobiście. Wymagało to nazwania wszystkiego w zbyt uproszczony sposób. Jeśli haczyk before NIE jest asynchroniczny, możesz użyć --require w swoim mocha.opts. na przykład

#mocha.opts 
--recursive 
--require test/helpers.js 

Brzmi to tak nie działa dla Ciebie, ponieważ chcemy globalnego after hak jak dobrze. To, co zrobiłem, to po prostu wywołanie zestawu testów za każdym razem, ale jeśli jestem w trakcie pracy i chcę tylko przetestować jeden pakiet, lub nawet jeden konkretny test, używam funkcji wyłączności, onlyhttps://mochajs.org/#exclusive-tests. Możesz to zrobić it.only('... lub describe.only('... Jeśli to zrobisz, przegląda wszystkie testy i ustawia dokładnie tak, jak zrobiłaby to twoja pełna uprząż testowa, ale wtedy wykonuje tylko test lub pakiet, który określiłeś.

Teraz możesz włączyć te globalne haki bez problemu. @Louis wspomina, że ​​twój helpers.js ładuje się w odpowiedniej kolejności tylko przypadkowo. To nie jest prawda. Jeśli umieścisz jakieś haki poza blokiem describe, automatycznie stanie się globalnym hakiem. Można to osiągnąć albo poprzez wprowadzenie go w jego własnym pliku

// helpers.js 
before(function() { console.log('testing...'); }); 

lub w pliku testowego

// some.spec.js 
before(function() { console.log('testing...'); }); 

describe('Something', function() { 
    it('will be tested', function() { 
    ... 
    }); 
}); 

Oczywiście, myślę, że wprowadzenie go w jego własnym pliku jest czystsze. (Nazwałem to hooks.js). Chodzi o to, że nie wynika to z kolejności ładowania plików.

Tylko jeden błąd, który może być oczywisty dla innych, ale ja zmagałem się z pokrótce - haki nie umieszczone w bloku describe są CAŁKOWITA. Nie są one specyficzne dla katalogu. Więc jeśli skopiujesz helpers.js do podkatalogu testów, hak before i after będzie teraz strzelał dwa razy. Ponadto, jeśli umieścisz tam hak beforeEach, wystrzeli on przed każdym pojedynczym testem, a nie tylko tymi testami w tym katalogu.

W każdym razie, wiem, że ten post jest trochę stary, ale mam nadzieję, że pomoże to innym osobom, które mają podobne problemy.

+1

Dzięki, ale Louis faktycznie był na dobrej drodze. Przyszedłem do mokki z innej struktury testowej, w której 'helper.js' zostałby automatycznie wywołany, to był mój problem. – Zlatko

+1

@Zlatko cieszy się, że znalazłeś dla siebie odpowiednie rozwiązanie. Stało się tak dlatego, że sam miałem podobne problemy i chciałem podzielić się moimi doświadczeniami. Mam też nadzieję, że zdajesz sobie sprawę, że niektóre z tego, co Louis powiedział o zamówieniu ładunku, były w rzeczywistości błędne. Możesz tworzyć globalne przechwyty, po prostu nie możesz wywołać testu dla pojedynczego pliku. – aray12

+0

Tak, od tamtego czasu wymyśliłem wiele takich rzeczy;) – Zlatko

2

Doszedłem do tego pytania po wypróbowaniu różnych rzeczy, aby przetestować połączenie z bazą danych, a następnie przeprowadzić kilka testów crud na moim models.

Potem znalazłem mocha-prepare, który rozwiązał moje problemy.

W pliku helper.js można po prostu zdefiniować funkcję prepare.

prepare(done => { 
    console.log('do something asynchronously here') 
    done() 
}, done => { 
    console.log('asynchronously clean up after here') 
    done() 
}) 

działa przyjemnie.

+1

Tak, właśnie to robię, tylko bez modułu przygotowania do mokki, ustawiłem go ręcznie. – Zlatko

0

W naszym projekcie używamy pomocników trochę tak:

clientHelper = require("../../../utils/clientHelper") 

Musisz skonfigurować ścieżkę względną swojego pomocnika prawidłowo.

A potem nazywając go tak:

clientHelper.setCompanyId(clientId)