I'm testing this reducer:
const todo = (state = {}, action) => {
switch(action.type) {
case 'ADD_TODO':
return {
id: action.id,
text: action.text,
completed: false
}
case 'TOGGLE_TODO':
if(state.id !== action.id) {
return state;
}
return {...state, completed: !state.completed};
default:
return state;
}
}
const todos = (state = [], action) => {
switch(action.type) {
case 'ADD_TODO':
return [
...state,
todo(undefined, action)
]
case 'TOGGLE_TODO':
return state.map(item => todo(item, action));
default:
return state;
}
}
export default todos;
With this test:
import todos from './todos';
test('creates a new todo', () => {
const stateBefore = [];
const action = {
type: 'ADD_TODO',
id: 0,
text: 'test'
};
const stateAfter = [{
id: 0,
text: 'test',
completed: false
}];
expect( JSON.stringify( todos(stateBefore, action) ) ).toBe( JSON.stringify(stateAfter) );
});
The problem is that my tests fail with a Compared values have no visual difference
remark if I remove the JSON.stringify()
calls - I get that comparing an object to an object poses some problems because of reference, but do I have to use JSON.stringify()
or loop through the object keys to compare them each time?
I'm answering my own question.
The .toBe
method tests for exact (===
) equality. In order to compare objects, you have to use the .toEqual
method which does recursive checks of every object key / array index, depending on your data type.
In conclusion, you don't have to use JSON.stringify()
and Jest goes through object keys for you, you just have to use the right equality testing method.
Source: https://facebook.github.io/jest/docs/using-matchers.html#content