Kiedy należy używać render i płytkiej powierzchni w testach Enzyme / React?


98

przed wysłaniem tego pytania próbowałem szukać w sqa stackexchange, ale nie znalazłem tam posta o płytkim i renderowanym, więc mam nadzieję, że ktoś może mi tutaj pomóc.

Kiedy powinienem używać płytkich i renderowanych w testach składników reagujących? Na podstawie dokumentacji airbnb przedstawiłem kilka opinii na temat różnicy między nimi:

  1. Ponieważ płytkie testuje komponenty jako całość , powinno być używane dla komponentów „macierzystych”. (np. tabele, opakowania itp.)

  2. Renderowanie dotyczy komponentów potomnych.

Powodem, dla którego zadałem to pytanie, jest to, że mam trudności z ustaleniem, którego powinienem użyć (chociaż doktorzy mówią, że są bardzo podobni)

Skąd więc mam wiedzieć, którego użyć w konkretnym scenariuszu?


2
Różnica między shallow () i mount () polega na tym, że shallow () testuje komponenty w oderwaniu od komponentów potomnych, które renderują, podczas gdy metoda mount () idzie głębiej i testuje elementy potomne komponentu. W przypadku shallow () oznacza to, że jeśli komponent nadrzędny renderuje inny komponent, który nie jest renderowany, wówczas renderowanie płytkie () na rodzica nadal będzie przebiegać.
Shyam Kumar

Odpowiedzi:


166

Zgodnie z dokumentacją Enzyme :

mount(<Component />) for Full DOM Renderowanie jest idealne do przypadków użycia, w których masz komponenty, które mogą współdziałać z DOM apis lub mogą wymagać pełnego cyklu życia, aby w pełni przetestować komponent (np. componentDidMount itp.)

vs.

shallow(<Component />) do renderowania płytkiego jest przydatne, aby ograniczyć się do testowania komponentu jako jednostki i upewnić się, że testy nie potwierdzają pośrednio zachowania komponentów potomnych.

vs.

renderktóry jest używany do renderowania komponentów reagujących na statyczny kod HTML i analizowania wynikowej struktury HTML.

Nadal możesz zobaczyć bazowe "węzły" w płytkim renderowaniu, więc na przykład możesz zrobić coś takiego (nieco wymyślny) przykład używając AVA jako elementu uruchamiającego specyfikację:

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

Zwróć uwagę, że renderowanie , ustawianie rekwizytów i znajdowanie selektorów, a nawet zdarzeń syntetycznych są obsługiwane przez płytkie renderowanie, więc w większości przypadków możesz po prostu tego użyć.

Ale nie będziesz w stanie uzyskać pełnego cyklu życia komponentu, więc jeśli spodziewasz się, że coś się wydarzy w componentDidMount, powinieneś użyć mount(<Component />);

Ten test wykorzystuje Sinon do szpiegowania komponentucomponentDidMount

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

Powyższe nie przejdzie przy płytkim renderowaniu lub renderowaniu

render udostępni tylko kod HTML, więc nadal możesz robić takie rzeczy:

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

    // insert Test component here...

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

mam nadzieję że to pomoże!


1
nadal nie rozumiem 100%, dlaczego te trzy czasowniki niosą ze sobą różne metody. Na przykład można użyć wrapper.getNode () w płytkim, ale nie w renderowaniu. jakieś wyjaśnienia / linki / dokumenty / blogi, które pomogłyby mi w uzyskaniu tego razem?
Paulquappe

@HenryZhu powinno jasno wynikać z dokumentów, że renderowanie jest bardziej zaangażowane niż płytkie, ponieważ w rzeczywistości próbuje naśladować drzewo DOM dla tego konkretnego węzła komponentu
WIEK

11
migracja enzymu z v2 do v3 spowodowała, że ​​metody cyklu życia są domyślnie włączone również w płytkiej wersji github.com/airbnb/enzyme/blob/master/docs/guides/ ...
Abhinav Singi


9

Różnica między shallow () a mount () polega na tym, że shallow () testuje komponenty w oderwaniu od komponentów potomnych, które renderują, podczas gdy metoda mount () przechodzi głębiej i testuje elementy potomne komponentu.

W przypadku shallow () oznacza to, że jeśli komponent nadrzędny renderuje inny komponent, który nie jest renderowany, wówczas renderowanie płytkie () na rodzica nadal będzie przebiegać.


Kiedy powinienem przetestować propskomponent, którego powinienem użyć shallowi mount?
Menai Ala Eddine - Aladdin
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.