2017-02-14 8 views
1

Ich habe Probleme mit der Methode contains von Enzyme, wenn es um den onClick-Handler einer Schaltfläche geht, bei dem die angegebene Aktionsmethode ein Argument erfordert. Ich lief in diese, während Reductions Aktionen an eine Komponente übergeben, aber ich werde hier vereinfachte Beispiele verwenden.Fehler beim Testen der Schaltfläche onClick-Handler mit dem Enzym

Sagen Sie zwei Methoden:

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

Sie übergeben sie an eine Komponente, und in dieser Komponente haben Sie zwei Tasten:

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

Als ich die erste Taste zu testen, gibt es kein Problem :

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

es passiert. Allerdings ist die zweite:

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

schlägt mit dem nicht hilfreich Ausgabe:

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) 

Ich habe versucht, mehr zu erfahren, indem sie alle Arten von Vergleichen versuchen, wie:

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); 

die Ergebnisse in:

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] 

Ich bin uns Jest als Test-Runner, und dies sowohl in der create-react-app- als auch in der react-boilerplate-Konfiguration. Irgendeine Idee, was ich falsch mache?

EDIT

Ich werde meine eigene Abhilfe in einer Antwort unten geben. Ich werde meinen tatsächlichen Code dort anstelle dieser Beispiele verwenden. Ich bin jedoch immer noch neugierig, warum der Test hier fehlschlägt ....

+0

Dieses Thema kann Ihr Problem nicht lösen? http: // Stapelüberlauf.com/questions/35478076/testing-react-component-onclick-event-mit-multiple-actions-in-it –

Antwort

1

Ich würde vorschlagen, Teststrategie zu überarbeiten.

Sie können HTML-Test dieser Art und Weise zu machen (mit 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()); 

und Komponente Interaktivität auf diese Weise (mit enzyme und sinon):

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

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

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

Wie Sie Jest verwenden, können Sie Verwenden Sie Jest Snapshots für die HTML-Überprüfung.

+0

Ich sehe, was du meinst, aber ich frage mich, wie praktisch es ist, wenn Sie react-boilerplate und styled-Komponenten verwenden. F.i. Die Klassennamen werden generiert, und ich scheine weniger explizites HTML zu schreiben, sondern verschachtelte Komponenten. Ich meine, es ist machbar, aber ich empfinde es als bequemer, Komponenten mit 'enthält' zu vergleichen. – devboell

+0

"und ich scheine weniger explizite html zu schreiben, sondern eher verschachtelte Komponenten" -> versteh das nicht – luboskrnac

+0

Ich kann mir keine Probleme mit gestylten Komponenten oder react-boilerplate vorstellen. – luboskrnac

0

(dies ist aus einem reagieren vorformulierten-Projekt, gestylt-Komponenten verwendet, die Tests bestehen, und die Abdeckung ist 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'); 
    }); 
}); 
Verwandte Themen