Reputation: 77
I've been playing around with this for a couple days now but can't get a simple '.toMatchSnapshot' to pass. I clearly don't understand how this works. Should i be changing the setup of my code or my test?
the code:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { ListGroup, ListGroupItem } from 'react-bootstrap';
import TodoItem from './TodoItem';
import TodoAPI from '../api/TodoAPI';
export class TodoList extends Component {
renderTodos = () => {
const { todos, toggleShowCompleted, searchInput } = this.props;
if (todos.length === 0) {
return (
<div>
<p>Nothing Scheduled To Do</p>
<hr />
</div>
);
}
return TodoAPI.filterTodos(
todos,
toggleShowCompleted,
searchInput
).map(todo => {
return (
<ListGroupItem key={todo.id}>
<TodoItem {...todo} />
</ListGroupItem>
);
});
};
render() {
return (
<ListGroup>
{this.renderTodos()}
</ListGroup>
);
}
}
function mapStateToProps({ todos, toggleShowCompleted, searchInput }) {
return { toggleShowCompleted, searchInput, todos };
}
export default connect(mapStateToProps)(TodoList);
the test:
import React from 'react';
import { shallow } from 'enzyme';
import { TodoList } from './TodoList';
describe('TodoList', () => {
const props = {
todos: { id: 1234, text: 'walk the cat' },
toggleShowCompleted: false,
searchInput: ''
};
const todoList = shallow(<TodoList {...props} />);
it('renders properly', () => {
expect(todoList).toMatchSnapshot();
});
});
the error:
FAIL src\components\TodoList.test.js ● TodoList › encountered a declaration exception
FAIL src\components\TodoList.test.js ● TodoList › encountered a declaration exception
TypeError: filteredTodos.filter is not a function
at Object.filterTodos (src/api/TodoAPI.js:27:33)
so it's erroring over my TodoAPI but i'm not sure how to fix this issue. here is the code for over in the 'TodoAPI.js'
const APIFunctions = {
setTodos(todos) {
if (Array.isArray(todos)) {
localStorage.setItem('todos', JSON.stringify(todos));
// return original array if if fails
return todos;
}
},
getTodos() {
const stringTodos = localStorage.getItem('todos');
let todos = [];
try {
todos = JSON.parse(stringTodos);
} catch (e) {
// stick with default array
}
// insure we actaully have an array and not any malicious code
return Array.isArray(todos) ? todos : [];
},
filterTodos(todos, showCompleted, searchInput) {
var filteredTodos = todos;
// filter by showCompleted
filteredTodos = filteredTodos.filter(todo => {
// if todo.completed === false continue to show the todo OR if showCompleted === true continue to show todo
return !todo.completed || showCompleted;
});
// filter by searchText
filteredTodos = filteredTodos.filter(todo => {
const text = todo.text.toLowerCase();
return searchInput.length === 0 || todo.text.indexOf(searchInput) > -1;
});
// sort todos with non-completed first
filteredTodos.sort((a, b) => {
// if a is not completed and b is completed a should come before b
if (!a.completed && b.completed) {
return -1;
// if a is completed and b isn't completed b should come before b
} else if (a.completed && !b.completed) {
return 1;
} else {
// a is equal to b and thus, no reason to sort
return 0;
}
});
return filteredTodos;
}, ...
Upvotes: 1
Views: 2377
Reputation: 884
Your unit test sets the prop todos
to be an object but your TodoAPI. filterTodos
method seems to be expecting an array instead. An object in JavaScript does not have a filter
method, hence the error message, whereas an array does.
My advice:
TodoAPI.filterTodos
. In a snapshot test, you're normally wanting to test the component rather than functions in other modules, like filterTodos
, that the component invokes. Such functions can be tested with their own unit tests.Upvotes: 3