2017-02-14 5 views
1

У меня возникла проблема с использованием метода Enzyme's contains, когда дело доходит до обработчика onClick на кнопке, где предоставленный метод действия требует аргумента. Я столкнулся с этим, передавая действия redux компоненту, но здесь я буду использовать упрощенные примеры.Кнопка проверки неполадок onClick handler with Enzyme

Скажем, у вас есть два метода:

const logClick =() => console.log('button was clicked'); 
const logClickWithArg = (message) => console.log('button was clicked: ', message); 

Вы передаете их к компоненту, и в этом компоненте у вас есть две кнопки:

<button 
    onClick={logClick} 
> 
    Click 
</button> 
<button 
    onClick={() => logClickWithArg('hello')} 
> 
    Click With Arg 
</button> 

Когда я тестирую первую кнопку, нет никаких проблем :

expect(wrapper.contains(
    <button 
     onClick={logClick} 
    > 
     Click 
    </button>)).toBe(true); 

проходит. Тем не менее, второй:

expect(wrapper.contains(
    <button 
     onClick={() => logClickWithArg('hello')} 
    > 
     Click 
    </button>)).toBe(true); 

терпит неудачу с бесполезным выходом:

expect(received).toBe(expected) 

    Expected value to be (using ===): 
     true 
    Received: 
     false 

     at Object.<anonymous>.it (src/App.test.js:42:3) 
     at process._tickCallback (internal/process/next_tick.js:103:7) 

Я пытался узнать больше, пробуя все виды сравнений, как:

console.log('first ', wrapper.find('button').first().props().onClick); 
console.log('last ', wrapper.find('button').last().props().onClick); 
expect(wrapper.find('button').first().props().onClick).toEqual(logClick); 
expect(wrapper.find('button').last().props().onClick).toEqual(logClickWithArg); 

который результаты:

console.log src/App.test.js:29 
    first () => console.log('button was clicked') 

    console.log src/App.test.js:30 
    last () => logClickWithArg('hello') 

expect(received).toEqual(expected) 

    Expected value to equal: 
     [Function logClickWithArg] 
    Received: 
     [Function onClick] 

Я - в Jest, как тест-бегун, и столкнулся с этим как в настройке create-react-app, так и в реакции-шаблоны. Любая идея, что я делаю неправильно?

EDIT

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

+0

Этот вопрос не может решить вашу проблему? Http: // StackOverflow.com/questions/35478076/testing-react-component-onclick-event-with-multiple-actions-in-it –

ответ

1

Я бы предложил пересмотреть стратегию тестирования.

Вы можете проверить HTML рендеринга таким образом (с помощью enzyme):

// GIVEN 
    const expectedNode = shallow(
     <div> 
      <button className="simple-button">Click</button> 
      <button>Click With Arg</button> 
     </div> 
    ); 

    // WHEN 
    const actualNode = shallow(<YourComponentName />); 

    // THEN 
    expect(actualNode.html()).to.equal(expectedNode.html()); 

и компонент интерактивность таким образом (с помощью enzyme и sinon):

// GIVEN 
    const clickCallback = sinon.spy(); 
    const actualNode = shallow(<YourComponentName onClick={clickCallback}/>); 

    // WHEN 
    actualNode.find(".simple-button").simulate("click"); 

    // THEN 
    sinon.assert.called(clickCallback); 

Как вы используете шутя, вы можете рассмотрите возможность использования Jest Snapshots для проверки HTML.

+0

Я понимаю, что вы имеете в виду, но мне интересно, насколько практично это использовать при использовании реактивных шаблонов и стилизованных компонентов. F.I. имена классов генерируются, и я, кажется, пишу меньше явных html, а скорее вложенных компонентов. Я имею в виду, что это выполнимо, но я чувствую, что сравнение компонентов с «содержит» более удобно. – devboell

+0

", и я, кажется, пишу менее явный html, но скорее вложенные компоненты" -> don; t понять это – luboskrnac

+0

Не могу придумать никаких проблем со стилизованными компонентами и не реагировать на шаблон. – luboskrnac

0

(это из-среагировать шаблонный проект, используя стилизованную-компоненту, тесты проходят и охват 100%)

index.js

import React, { PropTypes } from 'react'; 

import Menu from './Menu'; 
import MenuItem from './MenuItem'; 

const QuizModeSelector = ({ quizMode, onSetQuizMode }) => (
    <Menu> 
    <MenuItem 
     onClick={() => onSetQuizMode('pc')} 
     selected={quizMode === 'pc'} 
    > 
     Notes 
    </MenuItem> 
    <MenuItem 
     onClick={() => onSetQuizMode('pitch')} 
     selected={quizMode === 'pitch'} 
    > 
     Pitch 
    </MenuItem> 
    </Menu> 
); 

QuizModeSelector.propTypes = { 
    quizMode: PropTypes.string, 
    onSetQuizMode: PropTypes.func, 
}; 

export default QuizModeSelector; 

index.test.js

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

import QuizModeSelector from '../index'; 
import Menu from '../Menu'; 
import MenuItem from '../MenuItem'; 

describe('<QuizModeSelector />',() => { 
    const quizMode = 'pc'; 
    const onSetQuizMode = jest.fn(); 
    const props = { 
    quizMode, onSetQuizMode, 
    }; 

    const renderedComponent = shallow(<QuizModeSelector {...props} />); 

    it('should render a <Menu> tag',() => { 
    expect(renderedComponent.type()).toEqual(Menu); 
    }); 

    it('should contain 2 MenuItems',() => { 
    const items = renderedComponent.find(MenuItem); 
    expect(items).toHaveLength(2); 
    }); 

    it('should render a pc MenuItem',() => { 
    expect(renderedComponent.containsMatchingElement(
     <MenuItem 
     selected={quizMode === 'pc'} 
     > 
     Notes 
     </MenuItem> 
    )).toEqual(true); 
    }); 

    it('should render a pitch MenuItem',() => { 
    expect(renderedComponent.containsMatchingElement(
     <MenuItem 
     selected={quizMode === 'pitch'} 
     > 
     Pitch 
     </MenuItem> 
    )).toEqual(true); 
    }); 

    it('should handle click events',() => { 
    renderedComponent.find(MenuItem).first().simulate('click'); 
    expect(onSetQuizMode).toHaveBeenCalledWith('pc'); 
    renderedComponent.find(MenuItem).last().simulate('click'); 
    expect(onSetQuizMode).toHaveBeenLastCalledWith('pitch'); 
    }); 
}); 
Смежные вопросы