Функция jest spyOn называется
Я пытаюсь написать простой тест для простого компонента React, и я хочу использовать Jest, чтобы подтвердить, что функция была вызвана, когда я имитирую щелчок с помощью фермента. Согласно документам Jest, я должен иметь возможность использовать spyOn
для этого: spyOn.
однако, когда я пытаюсь это сделать, я продолжаю получать TypeError: Cannot read property '_isMockFunction' of undefined
что, как я понимаю, означает, что мой шпион не определен. Мой код выглядит так:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
myClickFunc = () => {
console.log('clickity clickcty')
}
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro" onClick={this.myClickFunc}>
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
);
}
}
export default App;
и в моем тестовом файле:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { shallow, mount, render } from 'enzyme'
describe('my sweet test', () => {
it('clicks it', () => {
const spy = jest.spyOn(App, 'myClickFunc')
const app = shallow(<App />)
const p = app.find('.App-intro')
p.simulate('click')
expect(spy).toHaveBeenCalled()
})
})
кто-нибудь есть понимание того, что я делаю неправильно?
3 ответов
Эй, приятель, я знаю, что немного опоздал, но ты почти закончил без каких-либо изменений, кроме того, как ты spyOn
.
Когда вы используете шпиона, вы должны наблюдать за прототипом компонента.
порядок прикрепления шпиона к прототипу класса и рендеринга (мелкая рендеринг) вашего экземпляра важны.
const spy = jest.spyOn(App.prototype, "myClickFn");
const instance = shallow(<App />);
на App.prototype
бит на первой строке есть то, что вам нужно, чтобы заставить вещи работать. В JavaScript class
не имеет своих методов, пока вы создайте его с помощью new MyClass()
, или вы окунетесь в MyClass.prototype
. Для вашего конкретного вопроса вам просто нужно было шпионить за App.prototype
метод myClickFn
.
надеюсь, это поможет кому-то еще, кто в противном случае попытается передать опору в свое приложение, чтобы сделать тестовый проход.
изменить:
Если вы хотите проверить побочные эффекты вашего myClickFn
вы можете просто вызвать ее в отдельном тесте.
const app = shallow(<App />);
app.instance().myClickFn()
/*
Now assert your function does what it is supposed to do...
eg.
expect(app.state("foo")).toEqual("bar");
*/
в вашем тестовом коде вы пытаетесь пройти App
функции spyOn, но spyOn будет работать только с объектами, а не классами. Как правило, вам нужно использовать один из двух подходов здесь:
1) где обработчик щелчка вызывает функцию, переданную как опора, например
class App extends Component {
myClickFunc = () => {
console.log('clickity clickcty');
this.props.someCallback();
}
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro" onClick={this.myClickFunc}>
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
);
}
}
теперь вы можете передать функцию шпиона в качестве опоры компоненту и утверждать, что она называется:
describe('my sweet test', () => {
it('clicks it', () => {
const spy = jest.fn();
const app = shallow(<App someCallback={spy} />)
const p = app.find('.App-intro')
p.simulate('click')
expect(spy).toHaveBeenCalled()
})
})
2) где обработчик щелчка устанавливает некоторое состояние компонента, например,
class App extends Component {
state = {
aProperty: 'first'
}
myClickFunc = () => {
console.log('clickity clickcty');
this.setState({
aProperty: 'second'
});
}
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro" onClick={this.myClickFunc}>
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
);
}
}
теперь вы можете делать утверждения о состоянии компонента, т. е.
describe('my sweet test', () => {
it('clicks it', () => {
const app = shallow(<App />)
const p = app.find('.App-intro')
p.simulate('click')
expect(app.state('aProperty')).toEqual('second');
})
})
вы почти там. Хотя я согласен с ответом @Alex Young об использовании реквизита для этого, вам просто нужна ссылка на instance
прежде чем пытаться шпионить за метод.
describe('my sweet test', () => {
it('clicks it', () => {
const app = shallow(<App />)
const instance = app.instance()
const spy = jest.spyOn(instance, 'myClickFunc')
instance.forceUpdate();
const p = app.find('.App-intro')
p.simulate('click')
expect(spy).toHaveBeenCalled()
})
})
документы: http://airbnb.io/enzyme/docs/api/ShallowWrapper/instance.html