Reputation: 1492
I have a simple Reducer
const uid = () => Math.random().toString(34).slice(2);
const bots = (state = [] , action) => {
switch(action.type) {
case 'ADD_BOT':
return [
...state, {
id: uid(),
isDone: false,
text: action.bots.text
}
]
//this will fail
case 'ADD_BOT_THAT_MUTATES':
console.log("mutating");
action.bots.id = uid();
state.push(action.bots);
return state;
default:
return state;
}
}
export default bots
And my spec file is
import deepFreeze from 'deep-freeze';
import bots from '../bots';
describe('Simple test', () => {
function addBot(text) {
return {
type: 'ADD_BOT',
bots: {
id: 1,
isDone: false,
text: text
}
};
}
function addBotThatMutates(text) {
return {
type: 'ADD_BOT_THAT_MUTATES',
bots: {
id: 1,
isDone: false,
text: text
}
};
}
let state = [];
deepFreeze(state);
beforeEach(() => {
state = bots(state, addBot("initial"));
});
it('should fail due to deepFreeze', () => {
//create a payload
let payload = addBot("test 1234");
let payloadThatMutates = addBotThatMutates("test 5678");
state = bots(state, payload);
state = bots(state, payloadThatMutates);
expect(3).toEqual(state.length);
});
});
When I call the Reducer with state = bots(state, payload);
I expect it to return a non mutated array as I'm using an ES6 spread statement in the Reducer.
When I call state = bots(state, payloadThatMutates);
I was expecting an error flagged by deepFreeze. This is because in the Reducers I'm using state.push(action.bots);
which I understand will mutate.
But I don't get any errors and my resultant state is an array of 3 objects.
Do I have an incorrect Reducers or have I not understood deepFreeze ?
This Unit test is not working as I expect. But my App/Web code works if i call the 'ADD_BOT_THAT_MUTATES action and Reducer I get no updated state i.e. Redux mutates the state.
Or have I just done something plain stupid ?
Upvotes: 1
Views: 1805
Reputation: 1492
Since posting, I've managed to get my head around deepFreeze and mutations Below are my two tests that give the expected results
import deepFreeze from 'deep-freeze';
import bots from '../bots';
describe('Simple test', () => {
function addBot(text) {
return {
type: 'ADD_BOT',
bots: {
id: 1,
isDone: false,
text: text
}
};
}
function addBotThatMutates(text) {
return {
type: 'ADD_BOT_THAT_MUTATES',
bots: {
id: 1,
isDone: false,
text: text
}
};
}
let state;
beforeEach(() => {
state = []
state = bots(state, addBot("initial"));
});
it('should pass due to non-muting reducer ', () => {
//create a payload
let payload = addBot("test 1234");
let state2 = bots(state, payload);
//state has non mutated and state2 is a new array
expect(state.length).toEqual(1);
expect(state2.length).toEqual(2);
});
it('should fail due to deepFreeze', () => {
deepFreeze(state);
//create a payload
let payloadThatMutates = addBotThatMutates("test 5678");
//deepFreeze will throw 'object is not extensible' because state is now mutating because of the push in the the reducer
let state2 = bots(state, payloadThatMutates);
expect(state).toEqual(state2);
});
});
Hope this helps anyone
Upvotes: 1