[React Testing] Use Generated Data in Tests with tests-data-bot to Improve Test Maintainability

A really important aspect of TDD is the refactor phase. A critical piece to making your tests easier to maintain is using code structure and values to communicate what is important and what is not. We’ll use data generation with test-data-bot to communicate that the specific data values are irrelevant and it’s just what kind of data it is. Let’s refactor our tests to communicate this effectively.

 

Install:

yarn add test-data-bot

 

Test:

import React from 'react'
import { render, fireEvent, waitFor } from '@testing-library/react'
import { Redirect as MockRedirect } from 'react-router'
import { savePost as mockSavePost } from '../extra/api'
import { Editor } from '../extra/redirect'
import '@testing-library/jest-dom/extend-expect'
import {build, fake, sequence} from 'test-data-bot'

// Mock Router redirect
jest.mock('react-router', () => {
  return {
    Redirect: jest.fn(() => null),
  }
})

jest.mock('../extra/api')

afterEach(() => {
  jest.clearAllMocks()
})

const postBuilder = build('Post').fields({
    title: fake(f => f.lorem.words()),
    content: fake(f => f.lorem.paragraphs().replace(/\r/g, '')),
    tags: fake(f => [f.lorem.word(), f.lorem.word(), f.lorem.word()]),
  })
  
  const userBuilder = build('User').fields({
    id: sequence(s => `user-${s}`),
  })

test('renders a form with title, content, tags, and a submit button', async () => {
  mockSavePost.mockResolvedValueOnce()
  const fakeUser = userBuilder()
  const { getByLabelText, getByText } = render(<Editor user={fakeUser} />)
  const fakePost = postBuilder()
  getByLabelText(/title/i).value = fakePost.title
  getByLabelText(/content/i).value = fakePost.content
  getByLabelText(/tags/i).value = fakePost.tags.join(', ')
  const submitButton = getByText(/submit/i)

  fireEvent.click(submitButton)

  expect(submitButton).toBeDisabled()

  expect(mockSavePost).toHaveBeenCalledWith({
    ...fakePost,
    authorId: fakeUser.id,
  })
  expect(mockSavePost).toHaveBeenCalledTimes(1)

  await waitFor(() =>
    expect(MockRedirect).toHaveBeenCalledWith({ to: '/' }, {}),
  )
})

 

posted @ 2020-05-02 19:35  Zhentiw  阅读(269)  评论(0编辑  收藏  举报