Wann sollten Sie Render und Flach in Enzym- / Reaktionstests verwenden?

95

Bevor ich diese Frage gestellt habe, habe ich versucht, in sqa stackexchange zu suchen, aber ich habe dort keinen Beitrag über flach und rendern gefunden, also hoffe ich, dass mir hier jemand helfen kann.

Wann sollte ich beim Testen flache und rendernde Reaktionskomponenten verwenden? Basierend auf den Airbnb-Dokumenten habe ich einige Meinungen zum Unterschied der beiden abgegeben:

  1. Da flach Komponenten als Einheit testet , sollte es für übergeordnete Komponenten verwendet werden. (zB Tische, Wrapper usw.)

  2. Rendern ist für untergeordnete Komponenten.

Der Grund, warum ich diese Frage gestellt habe, ist, dass es mir schwer fällt, herauszufinden, welche ich verwenden soll (obwohl die Dokumente sagen, dass sie sich sehr ähnlich sind).

Woher weiß ich also, welches in einem bestimmten Szenario verwendet werden soll?

Cyval
quelle
2
Der Unterschied zwischen flat () und mount () besteht darin, dass flat () Komponenten isoliert von den untergeordneten Komponenten testet, die sie rendern, während mount () tiefer geht und die untergeordneten Komponenten einer Komponente testet. Für flat () bedeutet dies, dass, wenn die übergeordnete Komponente eine andere Komponente rendert, die nicht gerendert werden kann, ein flaches () Rendering auf der übergeordneten Komponente weiterhin erfolgreich ist.
Shyam Kumar

Antworten:

160

Gemäß den Enzymdokumenten :

mount(<Component />) Das vollständige DOM-Rendering ist ideal für Anwendungsfälle, in denen Komponenten vorhanden sind, die möglicherweise mit DOM-APIs interagieren oder den vollständigen Lebenszyklus benötigen, um die Komponente vollständig zu testen (z. B. componentDidMount usw.).

vs.

shallow(<Component />) for Shallow Rendering ist nützlich, um sich darauf zu beschränken, eine Komponente als Einheit zu testen, und um sicherzustellen, dass Ihre Tests nicht indirekt das Verhalten untergeordneter Komponenten bestätigen.

vs.

renderHiermit werden Reaktionskomponenten in statisches HTML gerendert und die resultierende HTML-Struktur analysiert.

Sie können die zugrunde liegenden "Knoten" weiterhin in einem flachen Render sehen, sodass Sie beispielsweise mit AVA als Spezifikationsläufer so etwas wie dieses (leicht erfundene) Beispiel ausführen können:

let wrapper = shallow(<TagBox />);

const props = {
    toggleValue: sinon.spy()
};

test('it should render two top level nodes', t => {
    t.is(wrapper.children().length, 2);
});

test('it should safely set all props and still render two nodes', t => {
    wrapper.setProps({...props});
    t.is(wrapper.children().length, 2);
});

test('it should call toggleValue when an x class is clicked', t => {
    wrapper.setProps({...props});
    wrapper.find('.x').last().simulate('click');
    t.true(props.toggleValue.calledWith(3));
});

Beachten Sie, dass das Rendern , das Setzen von Requisiten und das Finden von Selektoren und sogar synthetische Ereignisse durch flaches Rendern unterstützt werden. In den meisten Fällen können Sie dies also einfach verwenden.

Sie können jedoch nicht den gesamten Lebenszyklus der Komponente abrufen. Wenn Sie also erwarten, dass in componentDidMount etwas passiert, sollten Sie Folgendes verwenden mount(<Component />):

Dieser Test verwendet Sinon , um die Komponenten auszuspionierencomponentDidMount

test.only('mount calls componentDidMount', t => {

    class Test extends Component {
        constructor (props) {
            super(props);
        }
        componentDidMount() {
            console.log('componentDidMount!');
        }
        render () {
            return (
                <div />
            );
        }
    };

    const componentDidMount = sinon.spy(Test.prototype, 'componentDidMount');
    const wrapper = mount(<Test />);

    t.true(componentDidMount.calledOnce);

    componentDidMount.restore();
});

Das Obige wird mit flachem Rendern oder Rendern nicht bestanden

render wird Ihnen nur das HTML zur Verfügung stellen, so dass Sie immer noch solche Dinge tun können:

test.only('render works', t => {

    // insert Test component here...

    const rendered = render(<Test />);
    const len = rendered.find('div').length;
    t.is(len, 1);
});

hoffe das hilft!

4m1r
quelle
1
Ich bekomme immer noch nicht 100%, warum die drei Verben unterschiedliche Methoden mit sich bringen. Zum Beispiel kann man wrapper.getNode () im flachen, aber nicht im Render verwenden. Irgendwelche Erklärungen / Links / Dokumente / Blogs, die mir helfen, dieses Problem zu lösen?
Paulquappe
@ HenryZhu Aus den Dokumenten sollte klar sein, dass das Rendern mehr involviert als flach ist, da es tatsächlich versucht, den DOM-Baum für diesen bestimmten Komponentenknoten nachzuahmen
AGE
11
Die Enzymmigration von v2 nach v3 hat die Lebenszyklusmethoden standardmäßig auch in flachen Github.com/airbnb/enzyme/blob/master/docs/guides/…
Abhinav Singi
Eine gute zusätzliche Erklärung der Unterschiede finden Sie hier github.com/airbnb/enzyme/issues/465#issuecomment-227697726 und hier github.com/airbnb/enzyme/issues/465#issuecomment-229116418
Dmitry Gonchar
9

Der Unterschied zwischen flat () und mount () besteht darin, dass flat () Komponenten isoliert von den untergeordneten Komponenten testet, die sie rendern, während mount () tiefer geht und die untergeordneten Komponenten einer Komponente testet.

Für flat () bedeutet dies, dass, wenn die übergeordnete Komponente eine andere Komponente rendert, die nicht gerendert werden kann, ein flaches () Rendering auf der übergeordneten Komponente weiterhin erfolgreich ist.

Shyam Kumar
quelle