javascript - How to test class components in react - Stack Overflow

I am trying some unit testing, I created a sandbox with a fake example(in reality I have a form)class

I am trying some unit testing, I created a sandbox with a fake example (in reality I have a form)

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { number: 0 };    
  }

  handleSubmit = (number1, number2) => {
    this.setState({ number: this.handleMultiply(number1, number2) })
  }

  handleMultiply = (number1, number2) => {
    return number1 * number2
  }

  render() {
    const { number } = this.state;

    return (
      <div className="App">
        <form onSubmit={e => this.handleSubmit(3, 7)}>       
          <input type="submit" name="Submit" value="Multiply" />
        </form>
        <Table number={number} />
      </div>
    );
  }
}

export default App;

So my initial idea was to try to test the multiply function. And did this, which obviously doesn't work

import App from "../src/App";

test("Multiply", function() {
  const expected = 21;
  const result = App.handleMultiply(3, 7);
  expect(result).toBe(expected);
});

I get

_App.default.handleMultiply is not a function

Is my approach right? If yes then how do I test the functions? Else, should I test from a user point of view instead of for internal functions (this is what I read)? Should I test for the output on the screen (I don't think this is reasonable)?

I am trying some unit testing, I created a sandbox with a fake example https://codesandbox.io/s/wizardly-hooks-32w6l (in reality I have a form)

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { number: 0 };    
  }

  handleSubmit = (number1, number2) => {
    this.setState({ number: this.handleMultiply(number1, number2) })
  }

  handleMultiply = (number1, number2) => {
    return number1 * number2
  }

  render() {
    const { number } = this.state;

    return (
      <div className="App">
        <form onSubmit={e => this.handleSubmit(3, 7)}>       
          <input type="submit" name="Submit" value="Multiply" />
        </form>
        <Table number={number} />
      </div>
    );
  }
}

export default App;

So my initial idea was to try to test the multiply function. And did this, which obviously doesn't work

import App from "../src/App";

test("Multiply", function() {
  const expected = 21;
  const result = App.handleMultiply(3, 7);
  expect(result).toBe(expected);
});

I get

_App.default.handleMultiply is not a function

Is my approach right? If yes then how do I test the functions? Else, should I test from a user point of view instead of for internal functions (this is what I read)? Should I test for the output on the screen (I don't think this is reasonable)?

Share Improve this question edited Jan 20, 2020 at 4:44 Lin Du 103k136 gold badges334 silver badges568 bronze badges asked Jan 18, 2020 at 2:00 user3808307user3808307 1,11512 gold badges64 silver badges115 bronze badges 4
  • 2 You’re approaching this with the wrong mindset. Instead trigger the form submit then check to make sure state has been updated appropriately including the multiply logic. – Alexander Staroselsky Commented Jan 18, 2020 at 3:59
  • @AlexanderStaroselsky ok, thank you, I will try, and do a more specific question if i get stuck – user3808307 Commented Jan 18, 2020 at 4:25
  • @AlexanderStaroselsky what if the form in a child ponent and the submit handlers in the parent? Do I need to do integration tests there? – user3808307 Commented Jan 18, 2020 at 22:02
  • 1 It may be a matter of opinion but I’d definitely test these separately. The tests for the child would be that on submit it triggers the function passed from the parent via props then also to test that the state renders as you’d expect. For the parent, I’d trigger the event and make sure the state has been updated correctly. – Alexander Staroselsky Commented Jan 18, 2020 at 22:05
Add a ment  | 

1 Answer 1

Reset to default 4

You can use instance() method of enzyme to get the instance of React Component. Then, call handleMultiply method directly and make the assertion for it. Furthermore, if the handleMultiply method has a side-effect or very plicated calculations, you need to make a simple mocked return value for it. It will make an isolated test environment for handleSubmit method. This means handleSubmit method will not depend on the return value of the real implementation of handleMultiply method.

E.g.

app.jsx:

import React from 'react';
import { Table } from './table';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { number: 0 };
  }

  handleSubmit = (number1, number2) => {
    this.setState({ number: this.handleMultiply(number1, number2) });
  };

  handleMultiply = (number1, number2) => {
    return number1 * number2;
  };

  render() {
    const { number } = this.state;

    return (
      <div className="App">
        <form onSubmit={(e) => this.handleSubmit(3, 7)}>
          <input type="submit" name="Submit" value="Multiply" />
        </form>
        <Table number={number} />
      </div>
    );
  }
}

export default App;

table.jsx:

import React from 'react';

export const Table = ({ number: num }) => {
  return <div>table: {num}</div>;
};

app.test.jsx:

import App from './app';
import { shallow } from 'enzyme';

describe('59796928', () => {
  let wrapper;
  beforeEach(() => {
    wrapper = shallow(<App></App>);
  });
  describe('#handleSubmit', () => {
    it('should pass', () => {
      expect(wrapper.exists()).toBeTruthy();
      wrapper.find('form').simulate('submit');
      expect(wrapper.state()).toEqual({ number: 21 });
    });
  });
  describe('#handleMultiply', () => {
    it('should pass', () => {
      const p = wrapper.instance();
      const actual = p.handleMultiply(2, 10);
      expect(actual).toBe(20);
    });
  });
});

Unit test results with coverage report:

 PASS  src/stackoverflow/59796928/app.test.jsx (11.688s)
  59796928
    #handleSubmit
      ✓ should pass (16ms)
    #handleMultiply
      ✓ should pass (9ms)

-----------|----------|----------|----------|----------|-------------------|
File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files  |    90.48 |      100 |    85.71 |    94.44 |                   |
 app.jsx   |      100 |      100 |      100 |      100 |                   |
 table.jsx |       50 |      100 |        0 |    66.67 |                 4 |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        13.936s

Source code: https://github./mrdulin/jest-codelab/tree/master/src/stackoverflow/59796928

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745568008a4633511.html

相关推荐

  • javascript - How to test class components in react - Stack Overflow

    I am trying some unit testing, I created a sandbox with a fake example(in reality I have a form)class

    6小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信