2016-04-17 5 views
6

Ich lerne zu testen Reagieren Sie statusfreie Komponenten mit der ReactTestUtils Bibliothek. Das ist meine einfache Komponente:Funktionskomponenten mit renderIntoDocument testen

import React from 'react'; 

const Greeter = ({name,place}) => (
    <h1>Hello,{name}. Welcome to the {place}.</h1> 
); 

export default Greeter; 

Dies ist mein Test-Spezifikation, die renderIntoDocument zum Laufen zu bringen, wickelte ich meine Greeter Komponente in einem div als here vorgeschlagen:

import {expect} from 'chai'; 
import React from 'react'; 
import ReactTestUtils from 'react-addons-test-utils'; 
import Greeter from '../Greeter'; 

describe('Greeter Components',() => { 
    it('renders correctly',() => { 
    var component = ReactTestUtils.renderIntoDocument(<div> 
     <Greeter name="Vamsi" place="Hotel California"/> 
    </div>); 

    var hasH1 = ReactTestUtils.findRenderedDOMComponentWithTag(component,'h1'); 
expect(hasH1).to.be.ok; 
    }); 
}); 

erhalte ich die Fehler

findAllInRenderedTree (...): Instanz muss eine zusammengesetzte Komponente sein.

Ich stelle meinen Code als jsbin here zur Verfügung.

Antwort

12

Da den Funktionskomponenten keine Instanz zugeordnet ist, können Sie sie nicht direkt mit render oder renderIntoDocument verwenden. Der Versuch, die Funktionskomponente zu umbrechen, ist eine gute Idee, leider funktioniert ein div aus einem ähnlichen Grund nicht. DOM-Komponenten geben auch keine Komponenteninstanz zurück, sondern geben den zugrunde liegenden DOM-Knoten zurück.

Was ist zu sagen, dass Sie die Test-utils-Funktion oder native Komponenten nicht als die "root" -Komponente verwenden können, die Sie rendern. Stattdessen möchten Sie Ihre Funktionskomponenten in eine Wrapper-Komponente einbetten, die createClass verwendet oder React.Component erweitert. teaspoon:

class Wrapper extends React.Component { 
    render() { 
    return this.props.children 
    } 
} 

let component = renderIntoDocument(<Wrapper><Greeter /></wrapper> 

Gotcha ist wie dieses kann wie die beliebte Enzym, oder meine eigenen zu nehmen Grund genug, um die Verwendung eines Drittanbieter-Tests Bibliothek sein. Beide abstrahieren Probleme wie diese, indem Sie Funktionskomponenten für Sie nahtlos ein- und ausgliedern, sodass Sie sich keine Gedanken darüber machen müssen, welche Art von Komponente Sie rendern möchten.

+0

Das hat mir sehr geholfen – codeVerine

0

Wrapping Funktionskomponenten in einem <div> funktioniert für mich. Sie müssen nur für die Komponente, die Sie ein wenig anders testen wollen suchen, dh

const props = { p1: "1" } 
test('Foo renders correctly classed div',() => { 
    const cpt = TestUtils.renderIntoDocument(<div><Foo {...props} /></div>); 
    const myNode = ReactDOM.findDOMNode(cpt.childNodes[0]); 
    expect(myNode.className).toBe('my-class'); 
}); 

Mitteilung, die Sie myNode zum Testen mit cpt.childNodes[0]

0

Zur Verbesserung @ Kloster-Panik Antwort ausrichten können, meine zwei Cent:

Sie müssen keine Klasse für das erstellen. Tun Sie es dynamisch:

import createReactClass from 'create-react-class'; 

// need to be a class component 
const Clazz = createReactClass({ 
    render:() => { 
    return <YourFunctionalComponentName {...props} />; 
    }, 
}); 

ReactTestUtils.renderIntoDocument(<Clazz />);