Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Jest spyOn函数调用_Javascript_Reactjs_Testing_Jestjs_Enzyme - Fatal编程技术网

Javascript Jest spyOn函数调用

Javascript Jest spyOn函数调用,javascript,reactjs,testing,jestjs,enzyme,Javascript,Reactjs,Testing,Jestjs,Enzyme,我正试图为一个简单的React组件编写一个简单的测试,我想用Jest来确认在我模拟酶点击时调用了一个函数。根据Jest文档,我应该能够使用spyOn来完成以下操作: 然而,当我尝试此操作时,我不断得到TypeError:cannotread undefined的属性“\u isMockFunction”,这意味着我的间谍未定义。我的代码如下所示: import React, { Component } from 'react'; import logo from './logo.svg'; im

我正试图为一个简单的React组件编写一个简单的测试,我想用Jest来确认在我模拟酶点击时调用了一个函数。根据Jest文档,我应该能够使用
spyOn
来完成以下操作:

然而,当我尝试此操作时,我不断得到
TypeError:cannotread undefined
的属性“\u isMockFunction”,这意味着我的间谍未定义。我的代码如下所示:

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()
 })
})
从“React”导入React;
从“react dom”导入react dom;
从“./App”导入应用程序;
从“酶”导入{shallow,mount,render}
描述(‘我的甜蜜测试’,()=>{
它('点击它',()=>{
const spy=jest.spyOn(应用程序'myClickFunc')
常量app=shallow()
常量p=app.find(“.app intro”)
p、 模拟('单击')
expect(spy).tohavebeincalled()
})
})

有人知道我做错了什么吗?

在您的测试代码中,您正试图将
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()
 })
})
现在可以断言组件的状态,即

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');
 })
})
description('my sweet test',()=>{
它('点击它',()=>{
常量app=shallow()
常量p=app.find(“.app intro”)
p、 模拟('单击')
expect(app.state('aProperty')).toEqual('second');
})
})

你就快到了。尽管我同意@Alex Young answer关于使用道具的说法,但在尝试监视该方法之前,您只需要引用
实例

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()
 })
})
description('my sweet test',()=>{
它('点击它',()=>{

const-app=shallow(

除了如何使用spyOn外,几乎没有任何更改。 使用spy时,您有两个选项:
spyOn
App.prototype
,或component
component.instance()

const spy=jest.spyOn(Class.prototype,“method”)

在类原型上附加spy并呈现(浅层呈现)实例的顺序很重要

const spy = jest.spyOn(App.prototype, "myClickFn");
const instance = shallow(<App />);
此方法需要
React.Component
shallow/render/mount
实例可用。本质上
spyOn
只是在寻找要劫持的东西,然后推入
jest.fn()
。它可能是:

普通的
对象

const obj = {a: x => (true)};
const spy = jest.spyOn(obj, "a");
A

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实例

const component = shallow(<App />);
/*
component.instance()
-> {myClickFn: f(), render: f(), ...etc}
*/
const spy = jest.spyOn(component.instance(), "myClickFn");
这两种方法我都用过,也见过。当我有一个
beforeach()
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");
*/

在调用simulate click之前,调用forceUpdate将spy函数附加到实例:instance.forceUpdate()奇怪..我无法在类似的测试中使用上述方法,但将app render方法从'shall'更改为'mount'修复了它。你知道为什么这可能是修复程序吗/为什么这个测试不需要'mount'?@youngrrrrr也许你的函数依赖于DOM,而shallow没有生成DOM,而mount是一个完整的DOM渲染器g
forceUpdate
抓住了我们……看起来很奇怪,有人能解释吗?知道为什么我们强制更新时会这样吗:O.这太奇怪了!类是一个对象。
spyOn
ClassName一起工作。prototype
类不是一个对象。在经典的OO中,它是一个对象的蓝图,在JavaScript中,它是一个函数<代码>类型(A类{})==“函数”
当我们实例化一个类时,我们会根据该类的原型创建一个对象。一个类的原型是一个对象,如果我们愿意,我们可以监视方法。最终,根据我在您的答案下的评论,我们想要测试点击处理程序的效果,而不仅仅是它被调用。我偶然发现了这个问题,但它就是没有我似乎不合作。我正试图通过一个小测验,结果只是fails@Byrd我不知道你的意思。jest不工作,
spyOn
不工作,还是其他什么东西?你的
包.json
是否正确配置了如何配置jest?关于你的语句有很多问题。@AlexYoung方法是spied是任意的。到达方法的路径是任意的。示例代码有一个缺陷,它被解决了。最终,有人会有一个使用
spyOn
的用例,其中的组件不接受
道具,或者纯组件没有
状态
。对
原型
进行监视对我来说是100%成功的。这是真的吗“或a
React.Component.prototype
”后的代码块演示与第一个代码块不同的东西?@VictorCarvalho此技术不适合功能组件。这里的目标是监视功能组件没有的类方法。我建议为您的用例研究
测试库/react
const component = shallow(<App />);
/*
component.instance()
-> {myClickFn: f(), render: f(), ...etc}
*/
const spy = jest.spyOn(component.instance(), "myClickFn");
/*
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.
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");
*/
function Component({ myClickFn, items }) {
   const handleClick = (id) => {
       return () => myClickFn(id);
   };
   return (<>
       {items.map(({id, name}) => (
           <div key={id} onClick={handleClick(id)}>{name}</div>
       ))}
   </>);
}

const props = { myClickFn: jest.fn(), items: [/*...{id, name}*/] };
const component = render(<Component {...props} />);
// Do stuff to fire a click event
expect(props.myClickFn).toHaveBeenCalledWith(/*whatever*/);