ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React] React Testing Library
    ReactJS 2023. 11. 30. 02:22

    리액트 테스팅 라이브러리는 리액트 컴포넌트를 사용자 입장에 가깝게 테스트할 수 있는 도구이다. 예를 들어 <div>Hello World</div>라는 코드가 있다면, div 태그를 사용하는지보다 Hello World 메시지가 브라우저에 노출이 되는지 파악하는 것을 더 중요하다고 본다. 또한 컴포넌트를 사용하는 테스트 코드를 작성하면서 해당 컴포넌트의 인터페이스를 개발 전에 미리 점검하여 문제를 발견 및 수정할 수 있다는 장점이 있다. 그러므로 최대한 개발 전 혹은 바로 직후에 테스트 코드를 작성하는 것이 권고된다.

     

    초심자를 위한 React Testing Library

     

    여기서도 마찬가지로 BDD 스타일로 코드를 작성하는 것이 유리하다. 다만 보다 구체화를 해보자면, given-when-then 패턴을 찾을 수 있다. 예를 들어 아래 코드의 경우, 컴포넌트가 render된다는 조건이 주어질 시(given), input에 'New name'을 입력했을 때(When), setText 함수가 'New name'이라는 값과 함께 호출된다(Then)고 구조를 나눠볼 수 있다. 만약 복잡한 로직이 컴포넌트로부터 분리된다면, 여기서는 다음의 코드와 같이 호출이 되었는지만 검증하면 된다.

     

    여기서 render 함수와 같이 반복되는 코드들을 바깥으로 빼서 함수로 만들어(Extract Function) 해당 함수를 호출하는 식으로 간단히 작성할 수 있다. 또한 given에 대한 부분이 거슬린다면, it 바깥으로 뺀 뒤 beforeEach()에 넣어주는 방법도 있다.

    import { render, screen, fireEvent } from '@testing-library/react';
    
    import TextField from './TextField';
    
    const context = describe;
    
    describe('TextField', () => {
    	const text = 'Tester';
    	const setText = jest.fn();
    	
    	beforeEach(() => {
    		setText.mockClear();
    		// 또는 jest.clearAllMocks();	
    	});
    	
    	function renderTextField() {
    		render((
    			<TextField
    				label="Name"
    				placeholder="Input your name"
    				text={text}
    				setText={setText}
    			/>
    		));
    	}
    	
    	it('renders an input control', () => {
        		// when
    		renderTextField();
    
    		// then
    		screen.getByLabelText('Name');
    	});
    	
    	context('when user types text', () => {	
    		it('calls the change handler', () => {
            
            		// given
    			renderTextField();
    
    			// when
    			fireEvent.change(screen.getByLabelText('Name'), {
    				target: {
    					value: 'New Name',
    				},
    			});
    	
        			// then
    			expect(setText).toBeCalledWith('New Name');
    		});
    	});
    });

     

    API 호출과 같이 외부 의존성이 큰 코드를 작성해야 한다면, 해당 부분만 가짜로 구현할 필요가 있을 때가 있다. 예를 들어 매번 서버를 키기 어렵거나, 실제로 post 요청을 해버려서 서비스단이 바뀐다거나 하는 등의 문제가 발생할 수 있기 때문이다. 이런 경우에는 Mocking을 활용하여 아래와 같이 불러오는 데이터의 가짜를 만들 수 있다. 또한 가짜 데이터들이 많이 필요한 경우, 따로 흩어져있는 데이터들을 fixture라는 파일에 한꺼번에 불러와 테스트 시 간편하게 fixture 파일 하나에서 불러와서 작업을 할 수 있다.

    import { render, screen } from '@testing-library/react';
    
    import App from './App';
    
    jest.mock('./hooks/useFetchProducts', () => () => [
    	{
    		category: 'Fruits', price: '$1', stocked: true, name: 'Apple',
    	},
    ]);
    
    test('App', () => {
    	render(<App />);
    
    	screen.getByText('Apple');
    });

     

    일반적으론 백엔드와 소통하는 부분이 차지하는 비중이 큰데, 이 부분을 하나씩 가짜 구현으로 바꾸다 보면 어려울 때가 있다. 이럴 땐 MSW 등 다른 대안을 고려해 보자.

    'ReactJS' 카테고리의 다른 글

    [React] Layered Architecture & Flux Architecture  (1) 2023.12.08
    [React] TDD  (0) 2023.11.29
    [React] React의 Component와 State  (2) 2023.11.23
    [React] REST API와 GraphQL  (4) 2023.11.22
    [React] VDOM(Virtual DOM)이란?  (2) 2023.11.20
Designed by Tistory.