4. 이름 목록 테스팅

이번에는, Names 관련 기능을 위한 테스트 코드를 작성해보겠습니다.

리듀서 작성

아까와 같은 원리로, 리듀서를 위한 테스트 코드를 작성해보겠습니다. 이번에 작성 할 코드의 차이점은, 액션 생성 함수 테스트 부분을 그냥 toMatchSnapshot 을 통하여 비교해주었습니다. 스냅샷은, 꼭 컴포넌트 결과물이 아니여도, 뭐든지 비교 할 수 있습니다. 당연히, 리듀서의 상태 또한 비교하고 싶다면 할 수 있죠.

src/store/modules/names.test.js

import names, * as namesActions from './names';

describe('names', () => {
  describe('actions', () => {
    const actions = [
      namesActions.changeInput('input'),
      namesActions.insert('name')
    ];
    it('should create actions', () => {
      expect(actions).toMatchSnapshot();
    })
  });

  describe('reducer', () => {
    let state = names(undefined, {});
    it('should return the initialState', () => {
      expect(state).toEqual({
        input: '',
        names: []
      });
    });

    it('should change input', () => { 
      state = names(state, namesActions.changeInput('hello'));
      expect(state).toHaveProperty('input', 'hello');
    });

    it('should insert', () => {
      state = names(state, namesActions.insert('hello'));
      expect(state.names).toEqual(['hello']);
      state = names(state, namesActions.insert('world'));
      expect(state.names).toEqual(['hello', 'world']);
    });
  });
});

코드가 아까보다 조금 더 많긴 하지만, 원리는 똑같으니, 새로 보는 코드는 딱히 없지요?

NameForm 테스트 작성하기

이번에는, NameForm 을 위한 테스트 코드를 작성해주겠습니다. 이 또한 이전에 했던 것과 비슷합니다. 클릭 대신 change 와 submit 이벤트를 발생시킬 뿐이죠.

src/components/NameForm.test.js

import React from 'react';
import { shallow } from 'enzyme';
import NameForm from './NameForm';

describe('NameForm', () => {
  let component = null;
  const mockChange = jest.fn();
  const mockSubmit = jest.fn();

  it('renders correctly', () => {
    component = shallow(
      <NameForm
        onChange={mockChange}
        onSubmit={mockSubmit}
        value="hello"
      />
    );
  });

  it('matches snapshot', () => {
    expect(component).toMatchSnapshot();
  });

  it('shows valid input value', () => {
    expect(component.find('input').props().value).toBe('hello');
  });

  it('calls onChange', () => {
    const mockedEvent = {
      target: {
        value: 'world'
      }
    };
    component.find('input').simulate('change', mockedEvent);
    expect(mockChange.mock.calls.length).toBe(1);
  })

  it('calls onSubmit', () => {
    component.find('form').simulate('submit');
    expect(mockSubmit.mock.calls.length).toBe(1);
  });
});

NameList 의 경우엔, 따로 기능이 있진 않으니, 그대로 두셔도 됩니다. 이미 스냅샷 테스팅이 되고있으니까요.

컨테이너 컴포넌트 만들기

이번에는, 한번 통합테스트를 해보겠습니다. 가짜 스토어가 아닌, 실제 스토어릁 넣어서, 액션이 디스패치 되고, 또 상태 값까지 제대로 변경시켜주는지 확인을 해보겠습니다.

src/containers/NameContainer.test.js

import React from 'react';
import { mount } from 'enzyme';
import NamesContainer from './NamesContainer';
import configureStore from '../store/configureStore';

describe('NamesContainer', () => {
  let component = null;
  let buttons = null;

  // 이번엔 실제 store 로 테스팅을 합니다.
  let store = configureStore();

  const context = { store };

  it('renders properly', () => {
    component = mount(<NamesContainer />, { context });
  });

  it('matches snapshot', () => {
    expect(component).toMatchSnapshot();
  });

  it('dispatches CHANGE_INPUT action', () => {
    const mockedEvent = {
      target: {
        value: 'world'
      }
    };
    component.find('input').simulate('change', mockedEvent);
    expect(store.getState().names.input).toBe('world');
  });

  it('dispatches INSERT action', () => {
    component.find('form').simulate('submit');
    expect(store.getState().names.names).toEqual(['world']);
  });

});

NamesContainer 도 테스팅을 모두 마쳤습니다! 유닛 테스트도 잘 되고, 통합 테스트도 잘 되니, 이 컴포넌트는 지금으로선 가히 완벽하다고 볼 수 있겠지요.

results matching ""

    No results matching ""