Реактивное контекстное тестирование - издевательство над потребителем в HOC - PullRequest
0 голосов
/ 04 декабря 2018

Я пытаюсь протестировать свой компонент, который использует данные из контекста через HOC.

Вот настройка: Модуль Mocked context /context/__mocks__

const context = { navOpen: false, toggleNav: jest.fn() } 

export const AppContext = ({
    Consumer(props) {
        return props.children(context)
    }
})

Higher OrderComponent /context/withAppContext

import React from 'react'
import { AppContext } from './AppContext.js'

/**
 * HOC with Context Consumer
 * @param {Component} Component 
 */
const withAppContext = (Component) => (props) => (
    <AppContext.Consumer>
        {state => <Component {...props} {...state}/>}
    </AppContext.Consumer>
) 

export default withAppContext

Компонент NavToggle

import React from 'react'
import withAppContext from '../../../context/withAppContext'

import css from './navToggle/navToggle.scss'

const NavToggle = ({ toggleNav, navOpen }) => (
    <div className={[css.navBtn, navOpen ? css.active : null].join(' ')} onClick={toggleNav}>
        <span />
        <span />
        <span />
    </div>
)

export default withAppContext(NavToggle)

И, наконец, набор тестов /navToggle/navToggle.test

import React from 'react'
import { mount } from 'enzyme'

beforeEach(() => {
  jest.resetModules()
}) 

jest.mock('../../../../context/AppContext')


describe('<NavToggle/>', () => { 
  it('Matches snapshot with default context', () => {    
        const NavToggle = require('../NavToggle')        
        const component = mount( <NavToggle/> )
        expect(component).toMatchSnapshot()
  })
})

Тест только начинается, но я сталкиваюсь с этой ошибкой: Warning: Failed prop type: Component must be a valid element type! in WrapperComponent Что, по моему мнению, является проблемой с HOC, следует ли мне посмеяться над этим как-то вместо AppContext, потому что технически AppContext не вызывается напрямую компонентом NavToggle, а вызывается в компоненте упаковки.

Заранее спасибо за любыевход.

1 Ответ

0 голосов
/ 06 декабря 2018

Итак, я решил это.

Было несколько проблем с моей попыткой выше.

  1. require не понимает экспорт по умолчанию, если вы его не указали
  2. mount blankКомпонент возвратил ошибку
  3. Перемешивание AppContext с файлом __mock__ вызвало проблему, когда я хотел изменить контекст для теста

Я решил это следующим образом.Я создал вспомогательную функцию mocking AppContext с пользовательским контекстом в качестве параметра

export const defaultContext = { navOpen: false, toggleNav: jest.fn(), closeNav: jest.fn(), path: '/' } 

const setMockAppContext = (context = defaultContext) => {
    return jest.doMock('../context/AppContext', () => ({
        AppContext: {
            Consumer: (props) => props.children(context)
        }
    }))  
}
export default setMockAppContext

И затем тестовый файл закончил выглядеть следующим образом

import React from 'react'
import { shallow } from 'enzyme'
import NavToggle from '../NavToggle'
import setMockAppContext, { defaultContext } from '../../../../testUtils/setMockAppContext'

beforeEach(() => {
  jest.resetModules()
}) 

describe('<NavToggle/>', () => { 
  //...   
  it('Should have active class if context.navOpen is true', () => {
    setMockAppContext({...defaultContext, navOpen: true})
    const NavToggle = require('../NavToggle').default //here needed to specify default export
    const component = shallow(<NavToggle/>)
    expect(component.dive().dive().hasClass('active')).toBe(true) //while shallow, I needed to dive deeper in component because of wrapping HOC   
  })
  //...
})

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...