I've got a Todo React Component that does an API call inside componentDidMount
and once the data is loaded, it will display it on the screen. While loading a text informing user about fetching will be shown.
Here is my todo.test.js
:
import React from 'react';
import ReactDOM from 'react-dom';
import renderer from 'react-test-renderer';
import { mount, shallow, render } from 'enzyme';
import Todo from '../components/Todo';
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import toJson from 'enzyme-to-json';
import {getTodos} from '../helpers/todo';
Enzyme.configure({ adapter: new Adapter() });
const mockTodos = { data: [{
"id": 4404,
"status": "active",
"text": "Shopping List"
}]};
jest.mock('../helpers/todo', () => ({
getTodos: jest.fn(() => {
return Promise.resolve(mockTodos);
})
}));
describe('Todo', () => {
it('works', () => {
const component = mount(<Todo timeout={2000} />);
expect(toJson(component)).toMatchSnapshot();
component.find("button").simulate("click");
expect(toJson(component)).toMatchSnapshot();
});
});
here is my helpers/todo.js
:
const mockTodos = { data: [{
"id": 7727,
"status": "completed",
"text": "Mocked Completed Todo"
}]};
export const getTodos = () => {
console.log("[][] Get Todos");
return new Promise((resolve, reject) => {
resolve(mockTodos);
});
};
and here is my todo.js
component:
import React from 'react';
import PropTypes from 'prop-types';
import TodoItem from './TodoItem';
import {getTodos} from '../helpers/todo';
class Todo extends React.Component {
constructor(props) {
super(props);
this.state = {
todos: [],
error: false,
loading: true
};
this.cancelAjaxRequests = false;
this.callApi = this.callApi.bind(this);
}
callApi() {
getTodos().then((json) => {
if (!this.cancelAjaxRequests) {
this.setState({
todos: json.data,
loading: false
});
}
});
}
componentDidMount() {
getTodos().then((json) => {
if (!this.cancelAjaxRequests) {
this.setState({
todos: json.data,
loading: false
});
}
});
}
componentWillUnmount() {
this.cancelAjaxRequests = true;
}
render() {
let content;
// TODO: add error handling
if (this.state.loading) {
return (
<div>
<div>
<button id="update-data" onClick={this.callApi}>Update State</button>
</div>
<p>Todos are being fetched...</p>
</div>
);
}
return (
content ||
<div>
<div>
<button id="update-data" onClick={this.callApi}>Update State</button>
</div>
<p><b>{this.state.todos.length}</b> todos fetched so far</p>
{this.state.todos.map(
(todo) => <TodoItem key={todo.id} id={todo.id} status={todo.status} text={todo.text} />)}
</div>
);
}
}
Todo.proptypes = {
timeout: PropTypes.number
};
export default Todo;
When running the tests the message from console.log("[][] Get Todos");
is displayed.
Aren't mocks supposed to actually mock the given function and not to call the original one? Why is it calling my getTodos
function?
Shouldn't only stick to return Promise.resolve(mockTodos);
from jest.mock
?
Aucun commentaire:
Enregistrer un commentaire