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)?
There are a few ways to test React components. Broadly, they divide into two categories: Rendering component trees in a simplified test environment and asserting on their output. Running a complete app in a realistic browser environment (also known as “end-to-end” tests).
You can change your components as much as you want as long as they render the data the same way or the React in the same way if you after interactions such as filling in data or pressing a button for example. It's a lightweight solution for testing React components. It provides utility functions on top of react-dom .
test. js extension as when the tests are run using the npm test command, React automatically checks for all the file names with a . test extension and runs the tests.
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 complicated 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 comp = wrapper.instance();
const actual = comp.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.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59796928
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With