如何使用enzyme测试函数式组件中的方法?由于shallow wrapper返回null,您需要使用instance()方法。

13

假设我有一个像这样简单的组件。

import React, { useState } from "react";

const Counter = () => {
  const [counter, setCounter] = useState(0);
  const incCounter = () => {
    setCounter(counter + 1);
  };
  return (
    <>
      <p>Counter value is: {counter}</p>
      <button className="increment" onClick={incCounter}>
        Up
      </button>
    </>
  );
};
export default Counter;

我想使用jest和enzyme编写测试用例。但counter.instance()始终返回null。 非常感谢任何帮助。

import React from "react";
import Counter from "../components/Counter";
import {
  mount,
  shallow
} from "./enzyme";

describe("Counter", () => {
  let counter;
  beforeEach(() => {
    counter = shallow( < Counter / > );
  })

  it("calls incCounter function when button is clicked", () => {
    console.log(counter)
    counter.instance().incCounter = jest.fn();
    const incButton = counter.find("button");
    incButton.simulate("click");
    expect(counter.incCounter).toBeCalled();

  })

});

1个回答

19

从这个文档中获取:https://airbnb.io/enzyme/docs/api/ShallowWrapper/instance.html

注意:只能在兼容根实例的包装器实例上调用。采用 React 16 及以上版本,对于无状态函数组件,instance() 返回 null。

测试组件行为,而不是实现细节。

例如:

index.jsx

import React, { useState } from 'react';

const Counter = () => {
  const [counter, setCounter] = useState(0);
  const incCounter = () => {
    setCounter(counter + 1);
  };
  return (
    <>
      <p>Counter value is: {counter}</p>
      <button className="increment" onClick={incCounter}>
        Up
      </button>
    </>
  );
};
export default Counter;

index.spec.jsx:

import React from 'react';
import Counter from './';
import { shallow } from 'enzyme';

describe('Counter', () => {
  let counter;
  beforeEach(() => {
    counter = shallow(<Counter />);
  });

  it('calls incCounter function when button is clicked', () => {
    expect(counter.find('p').text()).toBe('Counter value is: 0');
    const incButton = counter.find('button');
    incButton.simulate('click');
    expect(counter.find('p').text()).toBe('Counter value is: 1');
  });
});

单元测试结果,覆盖率达到100%:

 PASS  src/stackoverflow/59475724/index.spec.jsx (10.045s)
  Counter
    ✓ calls incCounter function when button is clicked (17ms)

-----------|----------|----------|----------|----------|-------------------|
File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files  |      100 |      100 |      100 |      100 |                   |
 index.jsx |      100 |      100 |      100 |      100 |                   |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        11.697s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59475724


我在文档中也发现了同样的问题。谢谢你详细的回复。 - Deepak Kumar Padhy
对我来说,props是必须的,但我使用jest时却没有覆盖到函数组件的方法。请帮忙。先谢谢了。 - jay rangras

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接