Nie ma domyślnej kolejności ładowania plików testowych przez Mocha.
Gdy Mocha skanuje katalog
aby znaleźć pliki to używa fs.readdirSync
. To wywołanie jest opakowaniem wokół readdir(3)
, co samo w sobie nie gwarantuje porządku. Teraz, ze względu na dziwactwo wdrożeniowe
wyjście fs.readdir i fs.readdirSync jest posortowany w systemie Linux (i prawdopodobnie ogólnie w systemach POSIX), ale nie w systemie Windows . Co więcej, możliwe jest, że posortowane zachowanie w systemie Linux może zostać ostatecznie usunięte, ponieważ dokumentacja mówi fs.readdir to po prostu readdir(3) a ten ostatni nie gwarantuje porządku. Można argumentować, że zachowanie zaobserwowane w systemie Linux jest błędem (patrz problem, do którego połączyłem się powyżej).
Zauważ, że istnieje --sort opcja, która posortuje pliki po ich znalezieniu przez Mocha. Ale to jest domyślnie wyłączone.
Obserwowane zachowanie można wytłumaczyć nie tylko kolejnością ładowania, ale także kolejnością wykonania . Oto, co się dzieje:
-
Mocha ładuje pliki testowe i wykonuje je. Tak więc wszystko, co znajduje się na najwyższym poziomie pliku, jest wykonywane od razu . Oznacza to, że kod w
test_helper.jswykonuje od razu. Każde wywołanieopisunatychmiast wykonuje swoje wywołanie zwrotne. Jednak wzywa dotozapisz test do późniejszego wykonania. Mocha odkrywa Twoje testy podczas wykonywania tego, ale nie wykonywania je od razu. -
Po wykonaniu wszystkich plików Mocha rozpoczyna testy. Do tego czasu kod w
test_helper.jsjuż został uruchomiony, a Twój test korzysta z utworzonego połączenia.
Poważne ostrzeżenie Połączenie z bazą danych jest operacją asynchroniczną i obecnie nic nie gwarantuje, że operacja asynchroniczna w test_helper.js zakończy się przed rozpoczęciem testów. To, że teraz działa dobrze, to tylko szczęście.
Gdybym to był ja, umieściłbym tworzenie połączenia w globalnym asynchronicznym przed hak. (globalny przed hook pojawiający się w dowolnym pliku testowym zostanie wykonany przed jakimkolwiek testem, nawet testami, które pojawiają się w innych plikach. ) Lub użyłbym --delay
i jawnie wywołaj run() aby uruchomić pakiet po zagwarantowaniu nawiązania połączenia.