Как написать модульный тест, чтобы проверить, появляется ли модальный после нажатия какой-либо ссылки - PullRequest
2 голосов
/ 13 апреля 2019

Я только изучаю юнит-тестирование с помощью Jest / Enzyme - специально для React / Redux. Я пытаюсь написать тест, чтобы проверить с точки зрения пользователя (это правильный подход? ...), если модал появляется после нажатия какой-либо ссылки. Далее я хочу проверить, закрывает ли shade обёртка над modal modal.

Модальное состояние (открыто / закрыто) контролируется Redux.

На основе текущего состояния из Redux - модал получает соответствующий стиль: modal или invisibleModal.

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

Тест до сих пор:

const mockFn = jest.fn();

describe('Contact components', ()=>{
    it('<ContactModal /> renders correctly', ()=>{
        shallow(<ContactModal />)
    })

    it('<ContactForm /> renders correctly', ()=>{
        shallow(<ContactForm toggleContactModal={mockFn} />)
    })

});

describe('In contact form link',()=>{
    const link = shallow(<ContactForm toggleContactModal={mockFn}/>)
    const modalWrapper = shallow(<ContactModal />);

    it('toggleContactModal function is called upon clicking ContactForm',()=>{
        expect(modalWrapper.find('#modal').hasClass('modal')).toBe(false);
        link.simulate('click');

        expect(mockFn.mock.calls.length).toBe(1);
    })
})

Модальный компонент:

export const ContactModal = props => {
    return (
        <>
            <div 
                id='modal' 
                className={props.contactModal ? styles.modal : styles.invisibleModal}
            >
                hello from modal
            </div>
            <div 
                id='shade' 
                className={props.contactModal ? styles.shade : styles.invisibleShade} 
                onClick={props.toggleContactModal}
                onKeyDown={props.toggleContactModal}
            />
        </>
    );
};

const mapStateToProps =state=> {
    return {
        contactModal: state.contactModal
    }
}

const mapDispatchToProps = {
    toggleContactModal
}

export default connect(mapStateToProps, mapDispatchToProps)(ContactModal);

Разбавление:

export const contactModal = (state=false, action) => {
    switch (action.type){
        case TOGGLE_CONTACT_MODAL:
            return !state;
        default:
            return state
    }
}

Заранее спасибо.

1 Ответ

1 голос
/ 13 апреля 2019

Из Письменных тестов Документ Redux:

... иногда вы хотите протестировать только рендеринг компонента без хранилища Redux.

Чтобы иметь возможность тестировать сам компонент приложения без необходимости иметь дело с декоратором, мы рекомендуем вам также экспортировать недекорированный компонент

Так что да, экспорт неподключенного компонента и его непосредственное тестирование - эторекомендуемый подход.


Для вашего компонента вам просто нужно протестировать изменения пользовательского интерфейса на основе contactModal prop и обработчиков нажатия и нажатия клавиш.

Вот несколько упрощенныйрабочий пример для начала работы:

import * as React from 'react';
import { shallow } from 'enzyme';

const ContactModal = props => {
  return (
    <>
      <div
        id='modal'
        className={props.contactModal ? 'modal': 'invisibleModal'}
      >
        hello from modal
          </div>
      <div
        id='shade'
        className={props.contactModal ? 'shade' : 'invisibleShade'}
        onClick={props.toggleContactModal}
        onKeyDown={props.toggleContactModal}
      />
    </>
  );
};

describe('ContactModal', () => {
  it('should render as expected when contactModal is true', () => {
    const wrapper = shallow(<ContactModal contactModal={true} />);
    expect(wrapper.find('#modal').prop('className')).toBe('modal');  // Success!
    expect(wrapper.find('#shade').prop('className')).toBe('shade');  // Success!
  });
  it('should render as expected when contactModal is false', () => {
    const wrapper = shallow(<ContactModal contactModal={false} />);
    expect(wrapper.find('#modal').prop('className')).toBe('invisibleModal');  // Success!
    expect(wrapper.find('#shade').prop('className')).toBe('invisibleShade');  // Success!
  });
  it('should call props.toggleContactModal on click', () => {
    const spy = jest.fn();
    const wrapper = shallow(<ContactModal contactModal={true} toggleContactModal={spy} />);
    wrapper.find('#shade').prop('onClick')();
    expect(spy).toHaveBeenCalled();  // Success!
  });
  it('should call props.toggleContactModal on keydown', () => {
    const spy = jest.fn();
    const wrapper = shallow(<ContactModal contactModal={true} toggleContactModal={spy} />);
    wrapper.find('#shade').prop('onKeyDown')();
    expect(spy).toHaveBeenCalled();  // Success!
  });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...