Próbuję dowiedzieć się, jak przetestować wewnętrzne (tj. Nie eksportowane) funkcje w nodejs (najlepiej z mokką lub jaśminem). I nie mam pojęcia!
Powiedzmy, że mam taki moduł:
function exported(i) {
return notExported(i) + 1;
}
function notExported(i) {
return i*2;
}
exports.exported = exported;
I następujący test (mokka):
var assert = require('assert'),
test = require('../modules/core/test');
describe('test', function(){
describe('#exported(i)', function(){
it('should return (i*2)+1 for any given i', function(){
assert.equal(3, test.exported(1));
assert.equal(5, test.exported(2));
});
});
});
Czy istnieje sposób na przetestowanie notExported
funkcji bez jej eksportowania, ponieważ nie jest przeznaczona do ujawnienia?
node.js
unit-testing
jasmine
mocha
xavier.seignard
źródło
źródło
Odpowiedzi:
ReWire moduł jest na pewno odpowiedź.
Oto mój kod dostępu do niewyeksportowanej funkcji i testowania jej za pomocą Mocha.
application.js:
test.js:
źródło
Cannot find module '../../package' from 'node.js'
. Widziałeś to?Sztuczka polega na ustawieniu
NODE_ENV
zmiennej środowiskowej na coś podobnego,test
a następnie warunkowym wyeksportowaniu.Zakładając, że nie masz globalnie zainstalowanej mokki, możesz mieć plik Makefile w katalogu głównym aplikacji, który zawiera następujące elementy:
Ten plik make ustawia NODE_ENV przed uruchomieniem mokki. Następnie możesz uruchomić testy mokki
make test
w wierszu poleceń.Teraz możesz warunkowo wyeksportować swoją funkcję, która zwykle nie jest eksportowana tylko wtedy, gdy są uruchomione testy mokka:
Druga odpowiedź sugerowała użycie modułu maszyny wirtualnej do oceny pliku, ale to nie działa i generuje błąd informujący, że eksport nie jest zdefiniowany.
źródło
EDYTOWAĆ:
Ładowanie modułu za pomocą
vm
może spowodować nieoczekiwane zachowanie (np.instanceof
Operator nie pracuje już z obiektami, które są tworzone w takim module, ponieważ prototypy globalne różnią się od tych używanych w module ładowanym normalnierequire
). Nie używam już poniższej techniki i zamiast tego używam modułu rewire . Działa wspaniale. Oto moja oryginalna odpowiedź:Rozwijając odpowiedź Srosha ...
Wydaje się to trochę hakerskie, ale napisałem prosty moduł "test_utils.js", który powinien pozwolić ci robić to, co chcesz, bez warunkowego eksportowania w modułach aplikacji:
Jest jeszcze kilka rzeczy, które są zawarte w
module
obiekcie globalnym modułu węzła, które mogą również wymagać przejścia docontext
powyższego obiektu, ale jest to minimalny zestaw, którego potrzebuję, aby działał.Oto przykład użycia mokki BDD:
źródło
rewire
?Współpracując z Jasmine, starałem się wejść głębiej w rozwiązanie zaproponowane przez Anthony'ego Mayfielda , oparte na rewire .
Zaimplementowałem następującą funkcję ( Uwaga : jeszcze nie do końca przetestowana, tylko udostępniona jako możliwa strategia) :
Dzięki takiej funkcji możesz szpiegować zarówno metody nieeksportowanych obiektów, jak i nieeksportowane funkcje najwyższego poziomu, w następujący sposób:
Następnie możesz ustawić takie oczekiwania:
źródło
możesz stworzyć nowy kontekst używając modułu vm i ewaluować znajdujący się w nim plik js, podobnie jak robi to repl. wtedy masz dostęp do wszystkiego, co zadeklaruje.
źródło
Znalazłem dość prosty sposób, który pozwala testować, szpiegować i mockować te wewnętrzne funkcje z poziomu testów:
Powiedzmy, że mamy taki moduł węzła:
Jeśli teraz chcesz przetestować i szpiega i mock
myInternalFn
natomiast nie eksportując go w produkcji musimy poprawić plik tak:Teraz możesz testować, szpiegować i wyszydzać
myInternalFn
wszędzie, gdzie go używasz, ponieważtestable.myInternalFn
w produkcji nie jest eksportowany .źródło
Nie jest to zalecana praktyka, ale jeśli nie możesz użyć
rewire
zgodnie z sugestią @Antoine, zawsze możesz po prostu przeczytać plik i użyćeval()
.Znalazłem to przydatne podczas testowania jednostkowego plików JS po stronie klienta dla starszego systemu.
Pliki JS utworzyłyby wiele zmiennych globalnych
window
bez żadnych instrukcjirequire(...)
imodule.exports
(i tak nie było żadnego pakietu modułów, takiego jak Webpack lub Browserify, który mógłby usunąć te instrukcje).Zamiast refaktoryzować całą bazę kodu, pozwoliło nam to zintegrować testy jednostkowe w naszym JS po stronie klienta.
źródło