5 votes

ReactJS : comment déclencher le réducteur avec une action dans Jest

Je travaille pour un test de réducteur. Mais l'état de retour du réducteur avec la fonction d'action est anormal.

reducer.react-test.js

import reducer from '../../test_module/reducer';

describe('Test Reducer', () => {

  const initStatus = { id: -1, list: [] };

  it('1. has default state', () => {    
    expect(reducer(initStatus, { type: 'unexpected' })).toEqual({
      ...initStatus
    });    
  });

  it('2. has added once', () => {    
    expect(reducer(initStatus, { type: "ADD" })).toEqual({
      ...initStatus,
      id: 0,
      list: [0],
    });   
  });

  it('3. has added twice', () => {    
    const afterAddOnce = reducer(initStatus, { type: "ADD" });
    expect(reducer(afterAddOnce, { type: "ADD" })).toEqual({
      ...initStatus,
      id: 1,
      list: [0,1],
    });    
  });
})

réducteur.js

export default function reducer(state={
    id: -1, list: [],
  }, action) {
  switch(action.type) {

    case "ADD": {
      state.id = state.id + 1;
      state.list.push(state.id);
      return {
        ...state,
      };
    }
  }
  return state;
}

structure du dossier

.
├── __test__
│   └── test_module
│       └── reducer.react-test.js
└── test_module
    └── reducer.js

Mon premier et mon deuxième cas de test fonctionnent comme prévu.

Cependant, lorsque j'ai essayé de déclencher l'action deux fois, je stocke l'état de retour de la première action. Mais l'état de retour est inattendu, ce qui a exécuté ADD action deux fois. (Je m'attendais à une seule action)

J'ai donc obtenu ce résultat lorsque j'ai exécuté jest :

FAIL  __test__/test_module/reducer.react-test.js
  ● Test Reducer › has added twice

    expect(received).toEqual(expected)

    Expected value to equal:
      {"id": 1, "list": [0, 1]}
    Received:
      {"id": 2, "list": [0, 1, 2]}

    Difference:

    - Expected
    + Received

     Object {
    -  "id": 1,
    +  "id": 2,
       "list": Array [
         0,
         1,
    +    2,
       ],
     }

Je dois avoir mal compris l'utilisation de la fonction de déclenchement du réducteur avec l'action. J'espère obtenir une méthode appropriée pour déclencher le réducteur avec l'action et obtenir le résultat attendu.

3voto

dpaulus Points 337

Le coupable peut être trouvé dans votre réducteur, plus précisément dans ces lignes :

state.id = state.id + 1;
state.list.push(state.id);

Le réducteur ici est à la fois en train de muter l'état, et de retourner un nouvel état. La mutation de l'état est une mauvaise pratique, et peut provoquer des effets bizarres (comme celui que vous rencontrez).

Ainsi, le 2. a ajouté une fois incrémentera l'id à 0. Il restera en mémoire pendant le prochain test où initialStatus aura un identifiant de 0, et non de -1. Dans notre réducteur, état Les points suivants initialStatus . Donc appeler state.id = status.id + 1; incréments initialStatus et de même pour la liste. C'est pourquoi il semble que l'action ADD soit appelée trois fois.

S'éloigner des mutations dans le réducteur peut aider à résoudre ce problème.

case "ADD": {
    const newId = state.id + 1;

    return {
      id: newId,
      list: state.list.concat([newId])
    };
}

Rappelez-vous, ne modifiez jamais l'état dans un réducteur, renvoyez toujours le nouvel état à la place ! ( http://redux.js.org/docs/Troubleshooting.html#never-mutate-reducer-arguments )

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X