Zaczynam myśleć, że to nie jest możliwe, ale i tak chcę zapytać.
Chcę przetestować, czy jeden z moich modułów ES6 wywołuje inny moduł ES6 w określony sposób. Z Jasmine jest to bardzo łatwe -
Kod aplikacji:
// myModule.js
import dependency from './dependency';
export default (x) => {
dependency.doSomething(x * 2);
}
I kod testowy:
//myModule-test.js
import myModule from '../myModule';
import dependency from '../dependency';
describe('myModule', () => {
it('calls the dependency with double the input', () => {
spyOn(dependency, 'doSomething');
myModule(2);
expect(dependency.doSomething).toHaveBeenCalledWith(4);
});
});
Jaki jest odpowiednik Jest? Wydaje mi się, że jest to bardzo prosta rzecz, ale chcę oderwać włosy, próbując to rozgryźć.
Najbliższe, jakie przyszedłem, to zamiana import
s na require
s i przenoszenie ich wewnątrz testów / funkcji. Żadnej z tych rzeczy nie chcę robić.
// myModule.js
export default (x) => {
const dependency = require('./dependency'); // yuck
dependency.doSomething(x * 2);
}
//myModule-test.js
describe('myModule', () => {
it('calls the dependency with double the input', () => {
jest.mock('../dependency');
myModule(2);
const dependency = require('../dependency'); // also yuck
expect(dependency.doSomething).toBeCalledWith(4);
});
});
Jeśli chodzi o punkty bonusowe, chciałbym, aby wszystko działało, gdy funkcja wewnątrz dependency.js
jest domyślnym eksportem. Wiem jednak, że szpiegowanie domyślnych eksportów nie działa w Jasmine (a przynajmniej nigdy nie udało mi się go uruchomić), więc nie mam nadziei, że jest to możliwe w Jest.
źródło
import
s dorequire
s. Dzięki za heads-upy.Odpowiedzi:
Udało mi się to rozwiązać za pomocą włamania
import *
. Działa nawet w przypadku nazwanych i domyślnych eksportów!W przypadku nazwanego eksportu:
Lub w przypadku domyślnego eksportu:
Jak słusznie wskazał Mihai Damian poniżej, powoduje to mutację obiektu modułu
dependency
, a więc „przecieka” do innych testów. Jeśli więc zastosujesz to podejście, powinieneś zapisać oryginalną wartość, a następnie ustawić ją ponownie po każdym teście. Aby to zrobić z pomocą Jest, użyj metody spyOn () zamiast,jest.fn()
ponieważ obsługuje łatwe przywracanie pierwotnej wartości, dzięki czemu unika się wcześniej wspomnianego „wycieku”.źródło
dependency
plik znajduje się w tym samym pliku comyModule
, nie będzie działać.Musisz wyśmiewać moduł i sam ustawić szpiega:
źródło
babel-plugin-jest-hoist: The second argument of jest.mock must be a function.
więc kod nawet się nie kompiluje.jest.mock
jest względna do pliku testowego.__esModule: true
do obiektu próbnego . Jest to wewnętrzna flaga używana przez transpilowany kod do ustalenia, czy jest to transpilowany moduł es6 czy moduł commonjs.jest.mock('../dependency', () => ({ default: jest.fn() }))
Aby wyśmiewać domyślny eksport modułu zależności ES6 za pomocą jest:
Inne opcje nie działały w moim przypadku.
źródło
Dodając więcej do odpowiedzi Andreasa. Miałem ten sam problem z kodem ES6, ale nie chciałem mutować importu. To wyglądało okropnie. Więc to zrobiłem
I dodano plik dependence.js w folderze „__ mocks __” równolegle do pliku dependency.js. To zadziałało dla mnie. Dało mi to również możliwość zwrócenia odpowiednich danych z fałszywej implementacji. Upewnij się, że podałeś prawidłową ścieżkę do modułu, z którego chcesz się wyśmiewać.
źródło
__mocks__/translations.js
Plik eksportu domyślnie po prostujest.fn()
w coś takiego:export default jest.fn((id) => id)
jest.genMockFromModule
do generowania próbnych modułów z modułów. facebook.github.io/jest/docs/…export default jest.genMockFromModule('../dependency')
będą miały przypisane wszystkie swoje funkcjedependency.default
po wywołaniu `jest.mock ('.. dependence'), ale poza tym zachowują się zgodnie z oczekiwaniami.expect(???)
Szybkie przejście do 2020 roku, znalazłem ten link jako rozwiązanie. za pomocą tylko składni modułu ES6 https://remarkablemark.org/blog/2018/06/28/jest-mock-default-named-export/
Jedną rzeczą, którą musisz wiedzieć (co zajęło mi trochę czasu, aby to rozgryźć) jest to, że nie możesz wywołać jest.mock () w teście; musisz to nazwać na najwyższym poziomie modułu. Możesz jednak wywołać mockImplementation () w ramach poszczególnych testów, jeśli chcesz skonfigurować różne próby dla różnych testów.
źródło
Odpowiedź na pytanie jest już udzielona, ale możesz rozwiązać go w następujący sposób:
dependency.js
myModule.js:
myModule.spec.js:
źródło
Rozwiązałem to w inny sposób. Załóżmy, że masz plik dependence.js
Oprócz tego tworzę plik depdency.mock.js z następującą zawartością:
i w teście, zanim zaimportuję plik, którego używam zależności, używam:
źródło