bkdragon's log

[TEST] Redux 테스트 본문

concept

[TEST] Redux 테스트

bkdragon 2023. 7. 29. 18:21

테스트를 연습하기 위해 간단한 todo app을 react + typescript + jest + redux를 사용해서 만들어보았다.

직접 해본 결과 redux test 과정은 크게 두가지이다.

 

  1. reducer 테스트
  2. action 객체 생성 테스트 (dispatch 테스트)

 

이 두가지 테스트를 통해 redux의 기능이 정상 작동하는 것을 브라우저를 사용해 직접 테스트하지 않아도 알 수 있다.

 

reducer 테스트

 

store/_reducer/todo.ts

reducer를 이렇게 작성했다.

const TodoSlice = createSlice({
  name: 'todo',
  initialState: [] as StateProps,
  reducers: {
    addTodo: (state: StateProps, action: PayloadAction<TodoProps>) => {
      state.push(action.payload);
    },
    deleteTodo: (state: StateProps, action: PayloadAction<string>) => {
      const newState = state.filter((todo) => todo.id !== action.payload);
      return newState;
    },
    changeDone: (state: StateProps, action: PayloadAction<string>) => {
      const target = state.find((todo) => todo.id === action.payload);

      if (!target) return;

      target.done = !target.done;
    },
  },
});

 

 

test/todoReducer.test.ts

reducer가 정상적으로 동작하는지 테스트한다.

describe('todoReducer', () => {
  const sampleItem: TodoProps = {
    description: 'samplesample',
    done: false,
    id: '2',
  };

  context('addTodo 사용하면', () => {
    it('새 할 일이 추가된다.', () => {
      const newState = TodoReducer(initialState, addTodo(sampleItem));

      expect(newState).toHaveLength(2);
    });
  });

  context('changeDone 사용하면', () => {
    it('done 값이 바뀐다.', () => {
      const current = initialState[0].done;

      const newState = TodoReducer(initialState, changeDone('1'));

      expect(current).not.toBe(newState[0].done);
    });
  });

  context('deleteTodo 사용하면', () => {
    it('할 일이 삭제된다.', () => {
      const newState = TodoReducer(initialState, deleteTodo('1'));

      expect(newState).toHaveLength(0);
    });
  });
});

 

 

action 생성 테스트 (dispatch 테스트)

 

reducer를 실행하면 action 객체가 생성된다. 컴포넌트에서 action 객체가 생성되는 걸 확인한다면 reducer가 정상적으로 실행되었다고 생각할 수 있다.

text/todoContainer.test.tsx

context('할 일을 입력하고 등록 버튼을 클릭하면', () => {
    it('todo/addTodo 타입 액션이 생성 된다.', () => {
      const { input, submitbtn, store, container } = renderTodoContainer();

      expect(submitbtn).toBeDisabled();
      userEvent.type(input, 'sample');
      expect(submitbtn).toBeEnabled();

      userEvent.click(submitbtn);

      const actions = store.getActions();
      const actionType = 'todo/addTodo';

      expect(actions[0].type).toEqual(actionType);
      expect(container).toHaveTextContent('sample');
    });
  });

 

여기서 store는 redux-mock-store를 통해 mocking한 store이다. store의 getActions 메서드를 통해 상호작용 이후 생성된 action 객체를 배열로 얻을 수 있다.

 

 

이게 맞나?

이게 맞다. 일단 내 결론은 그렇다.

직접적인 동작은 테스트한 것이 아니여서 잘못된 것 같아 보일 수 있지만 reducer 함수가 정상적으로 작동하는지와 정상적으로 호출되는지를 확인했기 때문에 실제 동작을 테스트 한것으로 볼 수 있다....

 

 

 

고 생각한다!

'concept' 카테고리의 다른 글

module css, classnames로 조건부 스타일링  (0) 2023.08.07
Async Custom Hook Testing  (0) 2023.08.02
CORS 요리  (0) 2023.07.29
Promise 병렬로 처리하기  (1) 2023.07.29
[Redux] Redux Toolkit  (0) 2023.07.27