簡體   English   中英

Jest / React 測試庫:是否可以像 Cypress 一樣監視並等待 GraphQL 查詢?

[英]Jest / React Testing Library: Is it Possible to Spy on and Wait GraphQL Queries as with Cypress?

我的大部分測試經驗都來自 Cypress。 我正在嘗試使用 React 測試庫(以下稱為“RTL”)測試一些 React 組件。 我想知道我是否可以應用我在 Cypress 中使用的一些技術。

我的(網絡)應用程序有一部分顯示來自數據庫的搜索結果表。 搜索 API 在 GraphQL 中實現。 我們在前端使用 Apollo。 可以通過<FilterCheckbox/>組件過濾搜索。 它包括四個復選框和一個“全部清除”按鈕。 復選框 state 存儲在 Apollo 緩存中。

我正在為這個組件編寫規范。 我希望測試前兩個復選框是否默認選中,並且單擊“清除過濾器”會取消選擇它們。 我有以下內容:

import React from 'react'
import FilterCheckboxes from './FilterCheckboxes'
import { render, fireEvent } from 'Utils/test-utils'

import {
  getByText,
  getByTestId
} from '@testing-library/dom'

const props = {
  options: [
    { label: 'new', value: 'FRESH' },
    { label: 'active', value: 'ACTIVE' },
    { label: 'closed', value: 'CLOSED' },
    { label: 'removed', value: 'ARCHIVED' },
  ],
  statusArray: [
    'FRESH',
    'ACTIVE',
  ],
  cacheKey: 'status',
}

describe('FilterCheckboxes component', () => {
  const { container } = render(<FilterCheckboxes {...props} />)

  const checkNew = getByTestId(container,'checkbox_new')
    .querySelector('input[type="checkbox"]')

  const checkActive = getByTestId(container, 'checkbox_active')
    .querySelector('input[type="checkbox"]')

  const checkClosed = getByTestId(container,'checkbox_closed' )
    .querySelector('input[type="checkbox"]')

  const checkRemoved = getByTestId(container, 'checkbox_removed')
    .querySelector('input[type="checkbox"]')

  const clearButton = getByText(container, 'clear status filters')


  it('should render the checkboxes with the correct default state', () => {
    expect(checkNew).toHaveProperty('checked', true)
    expect(checkActive).toHaveProperty('checked', true)
    expect(checkClosed).toHaveProperty('checked', false)
    expect(checkRemoved).toHaveProperty('checked', false)
  })

  it('Should clear all checkboxes when clear filters is clicked', () => {
    fireEvent.click(clearButton)
    setTimeout(() => {
      expect(checkNew).toHaveProperty('checked', false)
      expect(checkActive).toHaveProperty('checked', false)
      expect(checkClosed).toHaveProperty('checked', false)
      expect(checkRemoved).toHaveProperty('checked', false)
    }, 500)
  })
})

測試通過了,但第二個測試只有在我執行 500 毫秒的任意延遲時才會通過。 沒有它,當expect()調用觸發時,復選框仍然在默認的 state 中。

如果這是賽普拉斯測試並且 onClick 稱為 REST API,我會這樣做:

cy.server()
cy.route('POST', '/foo/bar/v2', '@someAliasedFixture').as('fooBar')

cy.get('.my-button')
.click()
.then(() => {
    cy.wait('@fooBar')
    // continue test here as we know that the call completed
})

可以用 Jest / RTL / GraphQL / Apollo 做這樣的事情嗎?

更新:今天早上又看了一遍。 看來waitFor()是 function 旨在用於異步場景。 但是,如果我這樣做

it('should deselect checkboxes when Clear Filters is clicked', async () => {
  fireEvent.click(clearButton)
  waitFor(expect(checkNew).toHaveProperty('checked', false))
})

它只是失敗了,因為復選框仍然被選中。 當然有一種方法可以用 RTL 進行測試嗎?

根據我看過的示例,正統的方法似乎是將點擊處理程序 function 作為道具傳遞並expect().toHaveBeenCalled()調用。

那是對的嗎? 這對我來說似乎是錯誤的。 我的組件不是讓 onClick 處理程序響應點擊事件而觸發的原因。 React.js 實現了這一點。 在單擊<MyComponent onClick={foo}/>時檢查是否調用了foo()並不能測試我的代碼是否有效。 它正在測試 React.js 是否有效。

解決了! 感謝@flo:

  it('should render the checkboxes with the correct default state', () => {
    expect(checkNew).toBeChecked()
    expect(checkActive).toBeChecked()
    expect(checkClosed).not.toBeChecked()
    expect(checkRemoved).not.toBeChecked()
  })

  it('should deselect checkboxes when Clear Filters is clicked', async () => {
    fireEvent.click(clearButton)
    waitFor(() => {
      expect(checkNew).not.toBeChecked()
      expect(checkActive).not.toBeChecked()
      expect(checkClosed).not.toBeChecked()
      expect(checkRemoved).not.toBeChecked()
    })
  })

我同意,您應該像真實用戶一樣進行測試,因此您絕對應該測試復選框是否在正確的 state 中,而不是測試是否調用了點擊處理程序。 這就是促進反應測試庫的原因。

你確定嗎?

expect(checkNew).toHaveProperty('checked', false);

我從來沒有使用過這個,但是閱讀文檔我不確定這是否能完成這項工作( https://jestjs.io/docs/en/expect#tohavepropertykeypath-value )。 事實上,我不明白它是如何工作的。

您是否考慮使用https://github.com/testing-library/jest-dom ,特別是https://github.com/testing-library/jest-dom#tobechecked

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM