У меня (для демонстрационных целей) чрезвычайно простой компонент React:
import React, { Component } from 'react';
import { fetchUser, fetchNews } from '../../infrastructure/actions';
class Layout extends Component {
render() {
return (
<div />
);
}
}
export default Layout;
и простой тестовый снимок Jest:
import React from 'react';
import { shallow } from 'enzyme';
import Layout from '../Layout';
describe('rendering', () => {
it('should render valid snapshot when loading', () => {
const jsx = (<Layout />);
const element = shallow(jsx);
expect(element).toMatchSnapshot();
});
});
Соответствующей строкой здесь является
import { fetchUser, fetchNews } from '../../infrastructure/actions';
infrastructure/actions/index.js
- это файл-баррель, полный действий Redux, таким образом:
export { fetchNews, FETCH_NEWS } from './news/fetchNews';
export { fetchUser, FETCH_USER} from './user/fetchUser';
// ...etc
Моя проблема в том, что, хотя ничего в выражении import не используется в компоненте с мелкой визуализацией, отчет о покрытии кода Jest рассматривает КАЖДЫЙ модуль в файле infrastructure/actions/index.js
как импортированный и выполненный, оставляя меня с бесполезный отчет о покрытии кода, который выглядит следующим образом.
--------------------------------------------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
--------------------------------------------------|----------|----------|----------|----------|-------------------|
All files | 56.08 | 38.46 | 5.17 | 56.08 | |
display/containers | 100 | 100 | 100 | 100 | |
Layout.js | 100 | 100 | 100 | 100 | |
infrastructure/actions | 100 | 100 | 100 | 100 | |
index.js | 100 | 100 | 100 | 100 | |
infrastructure/actions/characters | 50 | 0 | 0 | 50 | |
fetchCharacters.js | 50 | 100 | 0 | 50 | 3 |
fetchedCharactersFailure.js | 50 | 100 | 0 | 50 | 3 |
fetchedCharactersSuccess.js | 50 | 100 | 0 | 50 | 3 |
untrackCharacter.js | 50 | 100 | 0 | 50 | 5 |
untrackCharacterFailure.js | 50 | 100 | 0 | 50 | 3 |
untrackCharacterSuccess.js | 50 | 100 | 0 | 50 | 3 |
upsertCharacter.js | 50 | 0 | 0 | 50 | 5 |
upsertCharacterFailure.js | 50 | 100 | 0 | 50 | 3 |
upsertCharacterSuccess.js | 50 | 100 | 0 | 50 | 3 |
infrastructure/actions/help | 50 | 100 | 0 | 50 | |
submitContactForm.js | 50 | 100 | 0 | 50 | 5 |
submitContactFormFailure.js | 50 | 100 | 0 | 50 | 3 |
submitContactFormSuccess.js | 50 | 100 | 0 | 50 | 3 |
infrastructure/actions/news | 50 | 100 | 0 | 50 | |
fetchNews.js | 50 | 100 | 0 | 50 | 3 |
fetchedNewsSuccess.js | 50 | 100 | 0 | 50 | 3 |
infrastructure/actions/public | 50 | 0 | 0 | 50 | |
fetchPublicThreads.js | 50 | 100 | 0 | 50 | 3 |
fetchPublicViews.js | 50 | 100 | 0 | 50 | 3 |
fetchedPublicThreadsFailure.js | 50 | 100 | 0 | 50 | 3 |
fetchedPublicThreadsSuccess.js | 50 | 100 | 0 | 50 | 3 |
fetchedPublicViewsFailure.js | 50 | 100 | 0 | 50 | 3 |
fetchedPublicViewsSuccess.js | 50 | 100 | 0 | 50 | 3 |
untrackPublicView.js | 50 | 100 | 0 | 50 | 5 |
untrackPublicViewFailure.js | 50 | 100 | 0 | 50 | 3 |
untrackPublicViewSuccess.js | 50 | 100 | 0 | 50 | 3 |
upsertPublicView.js | 50 | 0 | 0 | 50 | 5 |
upsertPublicViewFailure.js | 50 | 100 | 0 | 50 | 3 |
upsertPublicViewSuccess.js | 50 | 100 | 0 | 50 | 3 |
infrastructure/actions/tags | 50 | 100 | 0 | 50 | |
fetchTags.js | 50 | 100 | 0 | 50 | 3 |
fetchedTagsSuccess.js | 50 | 100 | 0 | 50 | 3 |
infrastructure/actions/threads | 50 | 0 | 0 | 50 | |
bulkUntrackThreads.js | 50 | 100 | 0 | 50 | 5 |
bulkUntrackThreadsFailure.js | 50 | 100 | 0 | 50 | 3 |
bulkUntrackThreadsSuccess.js | 50 | 100 | 0 | 50 | 3 |
bulkUpdateThreads.js | 50 | 100 | 0 | 50 | 5 |
bulkUpdateThreadsFailure.js | 50 | 100 | 0 | 50 | 3 |
bulkUpdateThreadsSuccess.js | 50 | 100 | 0 | 50 | 3 |
exportThreads.js | 50 | 100 | 0 | 50 | 5 |
exportThreadsFailure.js | 50 | 100 | 0 | 50 | 3 |
exportThreadsSuccess.js | 50 | 100 | 0 | 50 | 3 |
fetchActiveThreads.js | 50 | 100 | 0 | 50 | 3 |
fetchActiveThreadsStatus.js | 50 | 100 | 0 | 50 | 3 |
fetchArchivedThreads.js | 50 | 100 | 0 | 50 | 3 |
fetchedActiveThreadsFailure.js | 50 | 100 | 0 | 50 | 3 |
fetchedActiveThreadsStatusChunkFailure.js | 50 | 100 | 0 | 50 | 3 |
fetchedActiveThreadsStatusChunkSuccess.js | 50 | 100 | 0 | 50 | 3 |
fetchedActiveThreadsStatusFailure.js | 50 | 100 | 0 | 50 | 3 |
fetchedActiveThreadsStatusSuccess.js | 50 | 100 | 0 | 50 | 3 |
fetchedActiveThreadsSuccess.js | 50 | 100 | 0 | 50 | 3 |
fetchedArchivedThreadsFailure.js | 50 | 100 | 0 | 50 | 3 |
fetchedArchivedThreadsSuccess.js | 50 | 100 | 0 | 50 | 3 |
generateRandomThread.js | 50 | 100 | 0 | 50 | 5 |
generatedRandomThreadSuccess.js | 50 | 100 | 0 | 50 | 3 |
setFilteredTag.js | 50 | 100 | 0 | 50 | 3 |
untrackThread.js | 50 | 100 | 0 | 50 | 5 |
untrackThreadFailure.js | 50 | 100 | 0 | 50 | 3 |
untrackThreadSuccess.js | 50 | 100 | 0 | 50 | 3 |
upsertThread.js | 50 | 0 | 0 | 50 | 5 |
upsertThreadFailure.js | 50 | 100 | 0 | 50 | 3 |
upsertThreadSuccess.js | 50 | 100 | 0 | 50 | 3 |
infrastructure/actions/ui | 50 | 0 | 0 | 50 | |
closeBulkUntrackThreadsModal.js | 50 | 100 | 0 | 50 | 3 |
closeUntrackCharacterModal.js | 50 | 100 | 0 | 50 | 3 |
closeUntrackPublicViewModal.js | 50 | 100 | 0 | 50 | 3 |
closeUntrackThreadModal.js | 50 | 100 | 0 | 50 | 3 |
closeUpsertCharacterModal.js | 50 | 100 | 0 | 50 | 3 |
closeUpsertPublicViewModal.js | 50 | 100 | 0 | 50 | 3 |
closeUpsertThreadModal.js | 50 | 100 | 0 | 50 | 3 |
openBulkUntrackThreadsModal.js | 50 | 100 | 0 | 50 | 3 |
openUntrackCharacterModal.js | 50 | 100 | 0 | 50 | 3 |
openUntrackPublicViewModal.js | 50 | 100 | 0 | 50 | 3 |
openUntrackThreadModal.js | 50 | 100 | 0 | 50 | 3 |
openUpsertCharacterModal.js | 50 | 0 | 0 | 50 | 5 |
openUpsertPublicViewModal.js | 50 | 0 | 0 | 50 | 5 |
openUpsertThreadModal.js | 50 | 0 | 0 | 50 | 5 |
setActiveHelpTab.js | 50 | 100 | 0 | 50 | 5 |
setActiveSettingsTab.js | 50 | 100 | 0 | 50 | 5 |
setActiveToolsTab.js | 50 | 100 | 0 | 50 | 5 |
setMaintenanceModeOn.js | 50 | 100 | 0 | 50 | 3 |
toggleHeaderDropdown.js | 50 | 100 | 0 | 50 | 5 |
toggleMobileSidebar.js | 50 | 100 | 0 | 50 | 5 |
toggleNewsAside.js | 50 | 100 | 0 | 50 | 5 |
toggleSidebar.js | 50 | 100 | 0 | 50 | 5 |
infrastructure/actions/user | 50 | 100 | 0 | 50 | |
fetchUser.js | 50 | 100 | 0 | 50 | 3 |
fetchedUserFailure.js | 50 | 100 | 0 | 50 | 3 |
fetchedUserSuccess.js | 50 | 100 | 0 | 50 | 3 |
submitUserAccountInfo.js | 50 | 100 | 0 | 50 | 5 |
submitUserChangePassword.js | 50 | 100 | 0 | 50 | 5 |
submitUserForgotPassword.js | 50 | 100 | 0 | 50 | 5 |
submitUserLogin.js | 50 | 100 | 0 | 50 | 5 |
submitUserLogout.js | 50 | 100 | 0 | 50 | 5 |
submitUserRegistration.js | 50 | 100 | 0 | 50 | 5 |
submitUserResetPassword.js | 50 | 100 | 0 | 50 | 5 |
userAccountInfoFailure.js | 50 | 100 | 0 | 50 | 3 |
userAccountInfoSuccess.js | 50 | 100 | 0 | 50 | 3 |
userChangePasswordFailure.js | 50 | 100 | 0 | 50 | 3 |
userChangePasswordSuccess.js | 50 | 100 | 0 | 50 | 3 |
userForgotPasswordFailure.js | 50 | 100 | 0 | 50 | 3 |
userForgotPasswordSuccess.js | 50 | 100 | 0 | 50 | 3 |
userLoginFailure.js | 50 | 100 | 0 | 50 | 3 |
userLoginSuccess.js | 50 | 100 | 0 | 50 | 3 |
userRegistrationFailure.js | 50 | 100 | 0 | 50 | 3 |
userRegistrationSuccess.js | 50 | 100 | 0 | 50 | 3 |
userResetPasswordFailure.js | 50 | 100 | 0 | 50 | 3 |
userResetPasswordSuccess.js | 50 | 100 | 0 | 50 | 3 |
infrastructure/actions/userSettings | 50 | 100 | 0 | 50 | |
fetchUserSettings.js | 50 | 100 | 0 | 50 | 3 |
fetchedUserSettingsFailure.js | 50 | 100 | 0 | 50 | 3 |
fetchedUserSettingsSuccess.js | 50 | 100 | 0 | 50 | 3 |
setShowDashboardThreadDistribution.js | 50 | 100 | 0 | 50 | 5 |
updateUserSettings.js | 50 | 100 | 0 | 50 | 5 |
updatedUserSettingsFailure.js | 50 | 100 | 0 | 50 | 3 |
updatedUserSettingsSuccess.js | 50 | 100 | 0 | 50 | 3 |
infrastructure/constants | 100 | 100 | 100 | 100 | |
analytics.js | 100 | 100 | 100 | 100 | |
utility | 62.5 | 100 | 50 | 62.5 | |
testHelpers.js | 62.5 | 100 | 50 | 62.5 | 12,13,16 |
--------------------------------------------------|----------|----------|----------|----------|-------------------|
Излишне говорить, что это сводит на нет цель отчета о покрытии кода, поскольку ни один из этих файлов, кроме двух, даже не связан с тестируемым компонентом - и даже с теми, которые есть, их код не должен будет выполнен этим тестом.
Также следует отметить - внизу в отчете о покрытии кода он ссылается на analytics.js
, который фактически импортируется одним из дочерних файлов infrastructure/actions/index.js
, а не самим бочечным файлом, что означает, что покрытие каким-то образом путешествуя еще дальше вниз по дереву зависимостей.
Как только я удаляю строку, импортирующую действия, файл покрытия немедленно начинает себя снова и отражает только проверяемый компонент.
Это также происходит, если я импортирую компонент, который (предположительно) будет использоваться где-то в макете; Я сразу же начинаю видеть показания покрытия для этого компонента и его дочерних элементов до конца, хотя я выполняю только поверхностный рендеринг в тестируемом компоненте.
Я пытался использовать jest.mock()
, чтобы смоделировать этот импорт до запуска метода shallow()
, но, похоже, это не имеет никакого значения для вывода покрытия.
Все это заставляет меня поверить, что я сделал что-то не так в настройке своей тестовой среды; Буду признателен за любые указания о том, что может вызвать этот эффект.