[TDD] testing-library (integration test)

dev stefanCho·2021년 12월 11일
0

tdd

목록 보기
1/4

Integrating Test

unit test VS integration test

unit test

하나의 component에 대해서만 테스트한다. 즉, 다른 component와 interaction되는 것을 테스트하는 것이 아니므로 props를 임의값으로 넣어서 테스트한다.

integration test

integration test는 연결된 컴포넌트간의 동작에 대해서 테스트한다.

React Component

Todo.js, AddInput.js, TodoList.js 이렇게 3개의 컴포넌트에 대해서 integration test를 한다.

Todo.js

TodoList와 AddInput(Input폼, Add버튼 있음)을 갖고 있다.

import React, { useState } from 'react'
import AddInput from '../AddInput/AddInput'
import Header from '../Header/Header'
import TodoList from '../TodoList/TodoList'
import "./Todo.css"

function Todo() {

    const [todos, setTodos] = useState([])

    return (
        <div className="todo">
            <Header title="Todo" />
            <AddInput 
                setTodos={setTodos}
                todos={todos}
            />
            <TodoList 
                todos={todos}
                setTodos={setTodos}
            />
        </div>
    )
}

export default Todo

AddInput.js

Input폼과, Add Button을 갖고 있다.

import React, { useState } from 'react'
import "./AddInput.css"
import { v4 } from "uuid"

function AddInput({
    setTodos, todos
}) {

    const [todo, setTodo] = useState("")

    const addTodo = () => {
        let updatedTodos = [
            ...todos,
            {
                id: v4(),
                task: todo,
                completed: false
            }
        ]
        setTodos(updatedTodos);
        setTodo("")
    }

    return (
        <div className="input-container">
            <input 
                className="input" 
                value={todo} 
                onChange={(e) => setTodo(e.target.value)}
                placeholder="Add a new task here..."
            />
            <button 
                className="add-btn"
                onClick={addTodo}
            >
                Add
            </button>
        </div>
    )
}

export default AddInput

TodoList.js

Todo에 추가된 항목들을 표시한다.

import React from 'react'
import TodoFooter from '../TodoFooter/TodoFooter'
import "./TodoList.css"

function TodoList({
    todos, setTodos
}) {

    const updateTask = (id) => {
        let updatedTasks = todos.map((todo) => {
            if (todo.id === id) {
                todo.completed = !todo.completed;
                return todo
            } else {
                return todo
            }
        });
        setTodos(updatedTasks)
    }

    const calcNumberOfIncompletedTasks = () => {
        let count = 0;
        todos.forEach(todo => {
            if (!todo.completed) count++
        })
        return count
    }

    return (
        <div className="todolist-container">
            <div className="todos-container">
                <div>
                    {
                        todos.map((todo, index) => (
                            <div
                                className={`todo-item ${todo.completed && "todo-item-active"}`}
                                onClick={() => updateTask(todo.id)}
                                data-testid="todo-item"
                                key={index}
                            >
                                {todo.task}
                            </div>
                        ))
                    }
                </div>
            </div>
            <div>
                <TodoFooter
                    numberOfIncompleteTasks={calcNumberOfIncompletedTasks()}
                />
            </div>
        </div>
    )
}

export default TodoList

Test Code

AddInput.js에 input 입력을 하고, Add 버튼으로 아이템을 추가한다. 그러면 추가한 아이템은 TodoList에 표시된다. 2개의 아이템을 추가하고, length가 2인지 판단하는 테스트코드를 작성한다.

import { render, screen, fireEvent } from '@testing-library/react';
import Todo from '../Todo';
import { BrowserRouter } from 'react-router-dom';

const MockedTodo = () => {
  return (
    <BrowserRouter>
      <Todo />
    </BrowserRouter>
  )
}

const addInput = (values) => {
  values.forEach(value => {
    const inputEl = screen.getByPlaceholderText(/Add a new task here.../i)
    const btnEl = screen.getByRole('button', { name: /Add/i })
    fireEvent.change(inputEl, { target: { value } });
    fireEvent.click(btnEl);
  })
}

describe("Todo Test", () => {
  test("add new item", async () => {
    render(<MockedTodo />)
    addInput([
      "Learn Test Code",
      "Learn React LifeCycle"
    ])
    const todoItems = screen.getAllByTestId('todo-item');
    expect(todoItems.length).toBe(2)
  })
})
profile
Front-end Developer

0개의 댓글