Неглубокий юнит-ферментный тест генерирует покрытие для всего дерева приложений - PullRequest
0 голосов
/ 04 мая 2018

У меня (для демонстрационных целей) чрезвычайно простой компонент 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(), но, похоже, это не имеет никакого значения для вывода покрытия.

Все это заставляет меня поверить, что я сделал что-то не так в настройке своей тестовой среды; Буду признателен за любые указания о том, что может вызвать этот эффект.

1 Ответ

0 голосов
/ 04 мая 2018

Для любопытных я сделал еще несколько копаний и понял, что это действительно ожидаемое поведение - импортированный файл по умолчанию выполняется при импорте, поэтому пока ни одна из функций внутри импортированных файлов не была выполнена, строки, на которых они были инициализированы, но все еще страдали из-за того, что их импортировали.

Решением для этого является использование Jest mocking для имитации всего импорта, используемого тестируемой системой в рамках инициализации теста. Я добавил эту строку в конец тестового файла (Jest поднимает его в верхней части тестов во время выполнения):

jest.mock('../../../infrastructure/actions', () => ({}));

(т.е. когда импорт вызывает actions/index.js, затем импортируйте функцию, которая вместо этого возвращает пустой объект). И все вернулось на круги своя.

...