【问题标题】:Spying on React functional component method with jest and enzyme; Cannot spyOn on a primitive value用 jest 和酶窥探 React 功能组件方法;无法窥探原始值
【发布时间】:2020-02-24 04:41:22
【问题描述】:

我正在尝试测试一个 React 组件并确保当它的按钮被点击时,正确的方法被调用。但是,当我尝试运行测试并尝试监视该方法时,我收到以下消息:

错误:无法监视原始值;给定的未定义

如何测试单击按钮时是否调用了正确的方法?谢谢!

sampleComponent.jsx:

import * as React from 'react';

const SampleComponent = () => {
  const sampleMethod = () => {
    console.log('hello world');
  };

  return <button onClick={sampleMethod} type="button">Click Me</button>;
};

export default SampleComponent;

sampleComponent.test.jsx:

import * as React from 'react';
import { shallow } from 'enzyme';
import SampleComponent from './sample';

test('testing spy', () => {
  const spy = jest.spyOn(SampleComponent.prototype, 'sampleMethod');
  const wrapper = shallow(<SampleComponent />);
  wrapper.find('button').simulate('click');
  expect(spy).toHaveBeenCalled();
});

【问题讨论】:

    标签: reactjs unit-testing jestjs enzyme


    【解决方案1】:

    sample.js

    import * as React from 'react';
    
    export let util = {sampleMethod: null };
    
    const SampleComponent = () => {
      util.sampleMethod = () => {
        console.log('hello world');
      };
    
      return <button onClick={sampleMethod} type="button">Click Me</button>;
    };
    
    export default SampleComponent;
    

    sample.test.js

    import { shallow } from 'enzyme';
    import SampleComponent, {util} from './sample';
    
    test('testing spy', () => {
      const spy = jest.spyOn( util, 'sampleMethod' );
      const wrapper = shallow(<SampleComponent />);
      wrapper.find('button').simulate('click');
      expect(spy).toHaveBeenCalled(1);
    });
    

    我知道我回答迟了,但我认为这也会对其他一些开发者有所帮助

    【讨论】:

    • 无法窥探 sampleMethod 属性,因为它不是函数;改为未定义
    • 我已经更新了代码,希望对你有用。
    【解决方案2】:

    错误的意思是,你在函数组件SampleComponent中定义的函数sampleMethod没有在SampleComponent.prototype中定义。所以SampleComponent.prototype.sampleMethodundefined,开玩笑不能窥探undefined 的值。

    所以测试sampleMethod事件处理程序的正确方法是这样的:

    index.spec.tsx:

    import React from 'react';
    import SampleComponent from './';
    import { shallow } from 'enzyme';
    
    describe('SampleComponent', () => {
      test('should handle click correctly', () => {
        const logSpy = jest.spyOn(console, 'log');
        const wrapper = shallow(<SampleComponent></SampleComponent>);
        const button = wrapper.find('button');
        expect(button.text()).toBe('Click Me');
        button.simulate('click');
        expect(logSpy).toBeCalledWith('hello world');
      });
    });
    

    我们可以监视console.log,判断它是否被调用。

    100% 覆盖率的单元测试结果:

     PASS  src/react-enzyme-examples/02-react-hooks/index.spec.tsx
      SampleComponent
        ✓ should handle click correctly (19ms)
    
      console.log node_modules/jest-mock/build/index.js:860
        hello world
    
    -----------|----------|----------|----------|----------|-------------------|
    File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
    -----------|----------|----------|----------|----------|-------------------|
    All files  |      100 |      100 |      100 |      100 |                   |
     index.tsx |      100 |      100 |      100 |      100 |                   |
    -----------|----------|----------|----------|----------|-------------------|
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        5.036s
    

    依赖版本:

    "react": "^16.11.0",
    "enzyme": "^3.10.0",
    "enzyme-adapter-react-16": "^1.15.1",
    "jest": "^24.9.0",
    "jest-environment-enzyme": "^7.1.1",
    "jest-enzyme": "^7.1.1",
    

    【讨论】:

    • 正在监视 const logSpy = jest.spyOn(console, 'log'); 对功能组件的黑客攻击,我们不能监视实际的函数名称 sampleMethod 。此外,如果我们使用 类组件,我们可以使用函数名进行监视而不使用 console.log ,对吗?我的意思是 hack 很好,但我想知道我们在生产时不能保留控制台语句
    • 也使用 shallow 给我错误,mount 对我有用
    • 假设上面的 sampleMethod 有一些其他代码而不是 console.log 语句。谁能告诉我们应该如何编写 spyOn?
    • @karthikreddy 你应该spyOn sampleMethod 使用的依赖项。例如,如果在sampleMethod 内部调用了axois.get(...) 语句,您应该像这样监视它:jest.spyOn(axois, 'get').mockResolvedValue({})。在触发sampleMethod 后,您应该断言expect(axois.get).toBeCalled()console.log 仅用于演示目的
    • @slideshowp2 这是有道理的,因为我们并不真正想知道方法是否被调用,而是方法内部的操作是否成功执行。来自 Spying 依赖项的断言也断言该方法已被调用。
    猜你喜欢
    • 2020-12-06
    • 2017-02-27
    • 2021-11-02
    • 2018-09-15
    • 2016-10-08
    • 1970-01-01
    • 2015-06-14
    • 2020-10-30
    • 2018-08-25
    相关资源
    最近更新 更多