Quando dovresti usare render e shallow nei test Enzyme / React?


95

prima di inviare questa domanda, ho provato a cercare in sqa stackexchange ma non ho trovato alcun post su superficiale e renderizzare lì, quindi spero che qualcuno possa aiutarmi qui.

Quando dovrei usare shallow e render per testare i componenti reattivi? Sulla base dei documenti di airbnb, ho espresso alcune opinioni sulla differenza dei due:

  1. Poiché shallow sta testando i componenti come un'unità , dovrebbe essere usato per i componenti "genitore". (es. tavoli, wrapper, ecc.)

  2. Il rendering è per i componenti figlio.

Il motivo per cui ho posto questa domanda è che ho difficoltà a capire quale dovrei usare (anche se i documenti dicono che sono molto simili)

Quindi, come faccio a sapere quale usare in uno scenario specifico?


2
La differenza tra shallow () e mount () è che shallow () testa i componenti in isolamento dai componenti figli che rendono mentre mount () va più in profondità e testa i figli di un componente. Per shallow () ciò significa che se il componente genitore esegue il rendering di un altro componente che non riesce a eseguire il rendering, verrà comunque eseguito un rendering shallow () sul genitore.
Shyam Kumar

Risposte:


160

Secondo la documentazione Enzyme :

mount(<Component />) per il rendering Full DOM è ideale per i casi d'uso in cui si hanno componenti che possono interagire con le API DOM, o possono richiedere l'intero ciclo di vita per testare completamente il componente (ad esempio, componentDidMount ecc.)

vs.

shallow(<Component />) for Shallow rendering è utile per limitarti a testare un componente come un'unità e per assicurarti che i tuoi test non affermino indirettamente il comportamento dei componenti figli.

vs.

renderche viene utilizzato per rendere i componenti di reazione all'HTML statico e analizzare la struttura HTML risultante.

Puoi ancora vedere i "nodi" sottostanti in un rendering superficiale, quindi, ad esempio, puoi fare qualcosa di simile (leggermente artificioso) usando AVA come spec runner:

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

Si noti che il rendering , l' impostazione di oggetti di scena e la ricerca di selettori e persino eventi sintetici sono tutti supportati dal rendering superficiale, quindi la maggior parte delle volte puoi semplicemente usarlo.

Tuttavia, non sarai in grado di ottenere l'intero ciclo di vita del componente, quindi se ti aspetti che le cose accadano in componentDidMount, dovresti usare mount(<Component />);

Questo test utilizza Sinon per spiare i componenticomponentDidMount

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

Quanto sopra non passerà con il rendering superficiale o di rendering

render ti fornirà solo l'html, quindi puoi ancora fare cose come questa:

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

    // insert Test component here...

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

spero che questo ti aiuti!


1
Ancora non ottengo il 100%, perché i tre verbi portano con sé metodi diversi. Ad esempio si può usare wrapper.getNode () in shallow ma non in render. eventuali spiegazioni / link / docs / blog, che mi aiutano a ottenere questo insieme?
Paulquappe

@HenryZhu dovrebbe essere chiaro dai documenti che il rendering è più complicato che superficiale, poiché in realtà cerca di imitare l'albero DOM per quel particolare nodo componente
AGE

11
la migrazione degli enzimi dalla v2 alla v3 ha reso i metodi del ciclo di vita
attivi


9

La differenza tra shallow () e mount () è che shallow () testa i componenti in isolamento dai componenti figli che rendono mentre mount () va più in profondità e testa i figli di un componente.

Per shallow () ciò significa che se il componente genitore esegue il rendering di un altro componente che non riesce a eseguire il rendering, verrà comunque eseguito un rendering shallow () sul genitore.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.