concept
[TEST] Redux 테스트
bkdragon
2023. 7. 29. 18:21
테스트를 연습하기 위해 간단한 todo app을 react + typescript + jest + redux를 사용해서 만들어보았다.
직접 해본 결과 redux test 과정은 크게 두가지이다.
- reducer 테스트
- 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 함수가 정상적으로 작동하는지와 정상적으로 호출되는지를 확인했기 때문에 실제 동작을 테스트 한것으로 볼 수 있다....
고 생각한다!