2017-04-06 70 views
10

Niedawno chciałem przetestować, że niektóre niestandardowe metody są warunkowo wywoływane w metodzie componentDidMount komponentu React.Używanie Jest do śledzenia wywołania metody w componentDidMount

componentDidMount() { 
    if (this.props.initOpen) { 
    this.methodName(); 
    } 
} 

Używam żartem jak mój ramach testów, które obejmuje jest.fn() dla kpi/szpiegów. Czytałem, że byłoby to dość trywialne do testowania z Sinon, wykonując coś tak:

sinon.spy(Component.prototype, "methodName"); 
const wrapper = mount(<Component {...props} />); 
expect(wrapper.instance().methodName).toHaveBeenCalled(); 

Próbuję odtworzyć to z żartem tak:

Component.prototype.methodName = jest.fn(); 
const wrapper = mount(<Component {...props} />); 
expect(wrapper.instance().methodName).toHaveBeenCalled(); 

Ten kod kończy się niepowodzeniem i generuje następujący błąd:

jest.fn() value must be a mock function or spy. 
Received: 
    function: [Function bound mockConstructor] 

Czy można przetestować tę funkcję za pomocą Czy? A jeśli tak, to w jaki sposób?

Odpowiedz

18

Kluczem jest metoda jests spyOn. Powinno być tak:

const spy = jest.spyOn(Component.prototype, 'methodName'); 
const wrapper = mount(<Component {...props} />); 
wrapper.instance().methodName(); 
expect(spy).toHaveBeenCalled(); 

Jak znaleźć tutaj np: Test if function is called react and enzyme

Należy pamiętać, jest to również najlepsze praktyki, aby usunąć funkcję szpiegował po każdym przebiegu testu

let spy 

afterEach(() => { 
    spy.mockClear() 
}) 

https://facebook.github.io/jest/docs/en/jest-object.html#jestclearallmocks

+0

Dziękujemy! Wygląda na to, że pojawił się w 19.0.0, zaledwie kilka miesięcy temu. Nie mogę uwierzyć, że pominąłem to w dokumentacji. – seansean11

+0

Serdecznie zapraszamy – Jonathan

+0

Czy wywoła on funkcję 'methodName()' w Komponencie, czy tylko ją udaje? – prime

1

Wiem, że jest trochę za późno, ale natknąłem się na to i sugeruję, aby przetestować componentDidMount inicjuje połączenie do Twój zagnieżdżona sposób, że test powinien wyglądać mniej więcej tak:

Module

componentDidMount() { 
    if (this.props.initOpen) { 
    this.methodName(); 
    } 
} 

Test - Dobry

it('should call methodName during componentDidMount',() => { 
    const methodNameFake = jest.spyOn(MyComponent.prototype, 'methodName'); 
    const wrapper = mount(<MyComponent {...props} />); 
    expect(methodNameFake).toHaveBeenCalledTimes(1); 
}); 

Jeśli zadzwonisz componentDidMount wówczas twierdzenie, że methodName został powołany przez componentDidMount jest bardziej poprawny.

Test - Bad

it('should call methodName during componentDidMount',() => { 
    const spy = jest.spyOn(Component.prototype, 'methodName'); 
    const wrapper = mount(<Component {...props} />); 
    wrapper.instance().methodName(); 
    expect(spy).toHaveBeenCalled(); 
} 

Pisząc test jak to - wywołać metodę, a potem twierdzić, że została wywołana. Co oczywiście dało, żebyś tak to nazwał.

+0

Żadne z tych testów nie działa dla mnie, nie można go przekazać w ogóle. – Byrd

+0

Czy przekazujesz wszystkie rekwizyty wymagane przez Twój komponent? – hloughrey

+0

Wreszcie działało, potrzebowałem stworzyć dla niego instancję i wymusić na moim szpiegu. – Byrd