我正在尝试为一个简单的React组件编写一个简单的测试,并且我想使用Jest来确认我用酶模拟点击时已调用了一个函数。根据Jest文档,我应该能够使用spyOn它:spyOn。
spyOn
但是,当我尝试此操作时,我不断得到TypeError: Cannot read property '_isMockFunction' of undefined暗示我的间谍未定义的信息。我的代码如下所示:
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() }) })
有人了解我在做什么错吗?
嗨,伙计,我知道我来晚了,但是除了您的方式之外,您几乎已经完成,没有任何改变spyOn。当您使用的间谍,你有两个选择:spyOn在App.prototype或组件component.instance()。
App.prototype
component.instance()
const spy = jest.spyOn(Class.prototype,“ method”)
将间谍附加到类原型上并渲染(浅渲染)实例的顺序很重要。
const spy = jest.spyOn(App.prototype, "myClickFn"); const instance = shallow(<App />);
在App.prototype第一行位有你需要的东西,使事情的工作。在class您使用实例化javascript new MyClass()或将其浸入之前,javascript 没有任何方法MyClass.prototype。对于您的特定问题,您只需监视该App.prototype方法myClickFn。
class
new MyClass()
MyClass.prototype
myClickFn
jest.spyOn(component.instance(),“方法”)
const component = shallow(<App />); const spy = jest.spyOn(component.instance(), "myClickFn");
此方法要求a的shallow/render/mount实例React.Component可用。本质上spyOn就是在寻找可以劫持并推向市场的东西jest.fn()。它可能是:
shallow/render/mount
React.Component
jest.fn()
平原object:
object
const obj = {a: x => (true)}; const spy = jest.spyOn(obj, "a");
答class:
class Foo { bar() {} } const nope = jest.spyOn(Foo, "bar"); // THROWS ERROR. Foo has no "bar" method. // Only an instance of Foo has "bar". const fooSpy = jest.spyOn(Foo.prototype, "bar"); // Any call to "bar" will trigger this spy; prototype or instance const fooInstance = new Foo(); const fooInstanceSpy = jest.spyOn(fooInstance, "bar"); // Any call fooInstance makes to "bar" will trigger this spy.
或一个React.Component instance:
React.Component instance
const component = shallow(<App />); /* component.instance() -> {myClickFn: f(), render: f(), ...etc} */ const spy = jest.spyOn(component.instance(), "myClickFn");
或一个React.Component.prototype:
React.Component.prototype
/* App.prototype -> {myClickFn: f(), render: f(), ...etc} */ const spy = jest.spyOn(App.prototype, "myClickFn"); // Any call to "myClickFn" from any instance of App will trigger this spy.
我已经使用并看到了两种方法。当我有一个beforeEach()或beforeAll()块时,我可能会采用第一种方法。如果我只需要快速监视,我将使用第二个。只需注意附加间谍的顺序即可。
beforeEach()
beforeAll()
编辑:如果要检查您的副作用,您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"); */