test utilities를 사용한 예제

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {default as ReactTestUtils, act} from 'react-dom/test-utils';

let container;

beforeEach(()=> {
    container = document.createElement('div');
    document.body.appendChild(container);
});

afterEach(() => {
    document.body.removeChild(container);
    container = null;
});

it('renders hello name', () => {
    act(() => {
        ReactDOM.render(<App/>, container);
    });

    const name = container.querySelector('#name'); // 
    expect(name.value).toBe('world');
    const output = container.querySelector('#output');
    expect(output.innerHTML).toBe('hello world');

act() 내부에서 value를 변경하고 change 이벤트를 발생시켜도 name의 값이 변경되지 않는다. 이렇게 사용하는게 아닌가.

     act(() => {
         name.value = 'jongmin';
         //name.onchange(); 이것도 안 통한다.
         name.dispatchEvent(new Event('change'));
     });
     expect(output.innerHTML).toBe('hello jongmin');

대신 여기처럼 simulate를 사용해야 한다. 두가지 방법이 있으나 첫 방법이 더 깔끔하게 보인다.

    ReactTestUtils.Simulate.change(name, {target: {value:'jongmin'}});
    //or
    //name.value = 'jongmin';
    //ReactTestutils.Simulate.change(name);
    expect(output.innerHTML).toBe('hello jongmin');

});

react-testing-library를 사용한 예제

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import 'jest-dom/extend-expect';

import { render, cleanup, fireEvent } from 'react-testing-library';

it('renders text of textbox', () => {

    const {container, getByText, getByDisplayValue, getByLabelText} = render(<App/>);
    expect(container).toBeInTheDocument(); // extend-expect
    const name = getByLabelText('Name');
    expect(name.value).toBe('world');
    
    const output = getByText('hello world');
    fireEvent.change(name, {target: {value: 'jongmin'}});
    expect(output.innerHTML).toBe('hello jongmin');

    cleanup();
});