Интересно, что этот вопрос затрагивает некоторые более необычные аспекты JavaScript.
Что происходит
submitForm
изначально определяется как метод-прототип :
class Section extends React.Component {
...
submitForm() { ... }
...
}
... означает, что вы бы создали spy
следующим образом:
jest.spyOn(Section.prototype, 'submitForm');
... но затем оно переопределяется как свойство экземпляра в constructor
:
this.submitForm = this.submitForm.bind(this);
... означает, что вы бы сейчас создали spy
следующим образом:
jest.spyOn(wrapper.instance(), 'submitForm');
... но это все еще не работает, потому что onBlur
связывается напрямую до this.submitForm
во время render
:
<section onBlur={this.submitForm}>
Таким образом, способ, которым код в настоящее время написан, фактически делает невозможным шпионить за submitForm
, потому что для создания spy
требуется instance
, но instance
недоступен, пока компонент не рендерится и onBlur
привязывается непосредственно к this.submitForm
во время рендеринга.
Решение
Измените onBlur
на функцию, которая вызывает this.submitForm
, чтобы при каждом срабатывании onBlur
она вызывала текущее значение из this.submitForm
:
render() {
return (
<section onBlur={() => this.submitForm()}>
<form ref={this.formRef} action={url} method='post'>
<input type="text" name="something" />
</form>
</section>
);
}
... затем, когда вы замените submitForm
на spy
на instance
, spy
будет вызван, когда onBlur
выстрелит:
describe('Section', () => {
it('should submit form on blur', () => {
const wrapper = shallow(<Section content={{ body: [] }} />);
const spy = jest.spyOn(wrapper.instance(), 'submitForm');
wrapper.find('section').simulate('blur');
expect(wrapper.state().formSubmitted).toEqual(true);
expect(spy).toHaveBeenCalled(); // Success!
})
})