Тестирование мутаций с DeepFreeze для объектов Redux

У меня есть простой редуктор

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

И мой файл спецификаций

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);
    });
});

Когда я вызываю Редуктор с state = bots(state, payload); Я ожидаю, что он вернет не мутированный массив, так как я использую оператор распространения ES6 в редукторе.

Когда я звоню state = bots(state, payloadThatMutates); Я ожидал ошибку, отмеченную DeepFreeze. Это потому, что в редукторах я использую state.push(action.bots); который я понимаю, будет мутировать.

Но я не получаю никаких ошибок, и мое результирующее состояние представляет собой массив из 3 объектов.

У меня неправильные редукторы или я не понял deepFreeze?

Этот юнит-тест не работает, как я ожидаю. Но мой код приложения /Web работает, если я вызываю действие "ADD_BOT_THAT_MUTATES", а "Reducer" я не получаю обновленное состояние, т.е. Redux изменяет состояние.

Или я только что сделал что-то глупое?

1 ответ

С момента публикации я сумел разобраться с DeepFreeze и мутациями. Ниже приведены мои два теста, которые дают ожидаемые результаты.

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);
    });

});

Надеюсь, это кому-нибудь поможет

Другие вопросы по тегам