Я придерживаюсь следующего подхода:
- Звуковые зависимости , вызываемые явно тестируемым компонентом.
- Инициализирующий компонент с
shallow()
- пробует разные модификации
- Проверка компонента с помощью
.toMatchSnapshot()
Под "пробовать разные модификации" я имею в виду либо создание компонента с разными начальными props
, либо взаимодействие с внутренними элементами компонента 'props
.
test('closes list on button clicked', () => {
let wrapper = shallow(<MyComponent prop1={'a'} prop2={'b'} />);
wrapper.find('button').at(0).simulate('click');
expect(wrapper).toMatchSnapshot();
});
Таким образом, вам никогда не нужно тестировать методы отдельно. Почему я считаю, что это имеет смысл?
Несмотря на то, что все тесты для каждого метода пройдены успешно, мы все еще не можем сказать, работает ли он в целом (ложноположительная реакция).
Также, если мы сделаем какой-либо рефакторинг, такой как метод переименования, наши тесты на метод не пройдут. В то же время компонент все еще может работать отлично, и мы тратим больше времени на исправление тестов, просто чтобы они прошли (ложноотрицательная реакция).
С другой стороны, фокусируясь на результатах render()
(это то, что адаптер Enzyme делает под капотом .toMatchSnapshot()
matcher), мы проверяем, что делает наш элемент в рамках проекта React.
[UPD] Пример на основе вашего кода:
describe("<FetchData />", () => {
let wrapper;
global.fetch = jest.fn();
beforeEach(() => {
fetch.mockClear();
});
function makeFetchReturning(documents) {
fetch.mockImplementation(() => Promise.resolve({ json: () => documents }));
}
function initComponent() {
// if we run this in beforeEach we would not able to mock different return value for fetch() mock
wrapper = shallow(<FetchData />);
}
test("calls appropriate API endpoint", () => {
makeFetchReturning([]);
initComponent();
expect(fetch).toHaveBeenCalledWith("api/SampleData/GetDocuments");
});
test("displays loading placeholder until data is fetched", () => {
// promise that is never resolved
fetch.mockImplementation(() => new Promise(() => {}));
initComponent();
expect(wrapper).toMatchSnapshot();
});
test("looks well when empty data returned", () => {
makeFetchReturning([]);
initComponent();
expect(wrapper).toMatchSnapshot();
});
test("reloads documents and displays them", () => {
makeFetchReturning([]);
initComponent();
// no matter what values we include in mock but it should be something non-empty
makeFetchReturning([{fileName: '_', currentSite: '1', correctSite: '2'}]);
wrapper.find('button').at(0).simulate('click');
expect(fetch).toHaveBeenCalledTimes(2);
expect(wrapper).toMatchSnapshot();
})
});