JESTおよび反応試験ライブラリによる反応成分試験
Responseコンポーネントをテストすると、ユーザーがそれと対話するときにコンポーネントが機能すると確信します.私の最初の仕事のジュニア完全なスタック開発者として、私はそれが非常に私の現在のcodebaseを理解するのに役立つだけでなく、私は学習中に値を追加できるようになりました.
この記事は、私が研究している間に役に立つ情報と、遭遇したいくつかの課題に対する答えの要約です.私は、車輪を再発明することを望みません、しかし、彼らの経歴の同様のステージで他のものを助けるために.また、テストを書く際にいくつかの経験があると仮定します.
なぜJest and RTL (React Testing Library) ?
反応はOpenFeintをテストランナーとしてjestを推奨します(おそらく彼らはそれを維持するため)とRTLの選択のテストユーティリティとして.Jestテストは非常に高速です、それは設定するのは簡単です、そして、それは特定の機能を交換して、望ましい値を返すか、テスト主題がどのように機能を実行しているかについて確認することができるmock機能のような多くの強力な機能を持ちます.RTLは非常に簡単に設定するのは簡単です(非同期を含む)クエリを作成し、どのように構築されたため、それは良いテストを書くのを助けるでしょう.
Jest-Dom 必須ではありませんが、Jest Matcherを拡張しているので、テストを簡単に書くことができます.
toBe()
, toHaveBeenCalled()
) また、より明確なテストを書くことができます.もう一つの人気ツールEnzyme , しかし、多くはそれが悪いテスト慣行につながることができると信じています.主な関心事は、酵素がコンポーネントの内部動作をテストすることができる余分なユーティリティを提供することです.反応テストでチームが反応;したがって、状態などの反応の機能をテストする必要はありません.
componentDidMount
, など他のライブラリを使用することもできます.何をテストするには?
反応におけるコンポーネントテストのとき、フォーカスはユーザがどのように反応コンポーネントと対話するかを模写することにあるべきです.これは、ユーザが何をすべきか、またはテストすべきではないかどうかをテストする必要があることを意味し、実装をテストする代わりに(例えば、検索/入力フィールドの値を変更することができます)、レンダリングするとアプリケーションと対話することを意味します
componentDidMount
X回数と呼ばれます.テストを書くとき、自分自身に問い合わせる良い質問がいくつかあります.
どのようにテストを書くか?
だから、面白い部分には、どのようにJESTを使用してコンポーネントを反応テストする.
RTLの最も使用される関数は以下の通りです:
render
– コンポーネントのレンダリングcleanup
– がマウントされたrender
, and fireEvent
– クリックのようなイベントを発射する.expect
マッチしてjest.fn()
直接機能を偽造するjest.spyOn()
オブジェクトメソッドをモックするjest.mock()
モジュール全体です.jest.fn()
/spyOn()
/mock()
嘲笑された実装の有無にかかわらずrender
引数としてテスト件名を持つ関数-コンポーネントがコンテキストを消費するたびにコンテキストを提供します.また、このRouter Linkがこのコンポーネントで使用されるなら、プロパティラッパーと値MemoryRouter(反応ルータから輸入される)をもつオブジェクトを第2の引数として通過しなければなりません.必要に応じてMemoryRouterタグのコンポーネントをラップしますgetByRole()
) を呼び出して値をチェックするexpect()
に沿って適切なマッチ.ユーザ相互作用を複製するfireEvent
debug()
レンダリングを呼び出すメソッド.デバッグは、あなたのテストをデバッグするような状況のために反応木で何が描かれるかチェックすることにとって素晴らしいです.以下のコードを検索コンポーネントの例として使用します.
render = () => {
const {
validateSelection,
minCharacters,
placeholder,
inputFluid,
inputLabel,
clear
}: any = this.props
const { isLoading, value, results } = this.state
const icon = validateSelection ? (
<Icon name="check" color="green" />
) : (
<Icon name="search" />
)
return (
<Search
minCharacters={minCharacters}
loading={isLoading}
icon={icon}
onResultSelect={this.onResultSelect}
onSearchChange={this.onSearchChange}
results={results}
value={clear ? null : value}
fluid
placeholder={placeholder}
input={{ fluid: inputFluid, label: inputLabel }}
/>
)
}
上記の小道具や状態を破壊している.また、私たちはSemantic UI React Search
モジュールです.本質的には、上記の入力フィールドをレンダリングします.変更されると、それはonSearchChange
とセマンティックUIの反応は自動的に2つの引数を渡します.event
and data
(現在の値を含むすべての小道具).一つonSearchChange
’s仕事はAPIを呼び出して、現在の値と一致する結果を返すことです.以下は、このコンポーネントのテストです.
import '@testing-library/jest-dom/extend-expect'
import React from 'react'
import { render, cleanup, fireEvent } from '@testing-library/react'
import SearchField from './SearchField'
afterEach(cleanup)
jest.useFakeTimers()
test('<SearchField />', () => {
const handleResultSelectMock = jest.fn()
const apiServiceMock = jest
.fn()
.mockImplementation(() =>
Promise.resolve({ entity: { success: true, data: ['hello', 'adios'] } })
)
const { getByRole, debug } = render(
<SearchField
handleResultSelect={handleResultSelectMock}
apiService={apiServiceMock}
/>
)
const input = getByRole('textbox')
expect(apiServiceMock).not.toHaveBeenCalled()
expect(input).toHaveValue('')
fireEvent.change(input, { target: { value: 'search' } })
expect(input).toHaveValue('search')
jest.advanceTimersByTime(600)
expect(apiServiceMock).toHaveBeenCalledWith('search')
expect(apiServiceMock).toHaveBeenCalledTimes(1)
debug()
})
上の例で何が起こっているのですか.
このコンポーネントをテストするために必要なすべての依存関係をインポートしました.
render
, cleanup
, fireEvent
- テストライブラリユーティリティSearchField
- 被検査成分import '@testing-library/jest-dom/extend-expect'
import React from 'react'
import { render, cleanup, fireEvent } from '@testing-library/react'
import SearchField from './SearchField'
我々は、Jestの機能と呼ばれましたafterEach
とRTLのメソッドcleanup
議論として.cleanup
はRTLのマウントされた全てをアンマウントすることでテスト間のメモリリークがないことを確認しますrender
メソッド.また、ジェストのuseFakeTimers
機能モックタイマー機能.afterEach(cleanup)
jest.useFakeTimers()
コンポーネントは、関数でなければならない2つの小道具を必要とします.したがって、コンポーネントにpropsとして渡される2つの関数をmockkingすることから始めました.handleResultSelectMock
and apiServiceMock
. handleResultSelectMock
はhandleResultSelect
and apiServiceMock
to apiService
. そしてRTLのrender
SearchFieldコンポーネントを引数としてメソッドを呼び出します.test('<SearchField />', () => {
const handleResultSelectMock = jest.fn()
const apiServiceMock = jest
.fn()
.mockImplementation(() =>
Promise.resolve({ entity: { success: true, data: ['hello', 'adios'] } })
)
const { getByRole, debug } = render(
<SearchField
handleResultSelect={handleResultSelectMock}
apiService={apiServiceMock}
/>
)
})
テストされているコンポーネントがA
wrapper: Memory Router
またはcontext
成功する.以下の例を見てください.const { getByTestId, container } = render(
<UserContext.Provider value={context}>
<MainLoggedIn
config={{
get: jest.fn().mockImplementation(() => ({
globalMenu: [{ requiredPermissions: ['Navbar'] }]
}))
}}
history={{ history: ['first_history', 'second_history'] }}
children={['first_child', 'second_child']}
/>
</UserContext.Provider>,
{ wrapper: MemoryRouter }
)
アフターrender
が呼び出されると、反応するDOMツリーを問い合わせ、テストしたい要素を見つけます.下記使用getByRole
, しかし、RTLは他の多くのクエリセレクタ関数を提供します.const input = getByRole('textbox')
値をチェックするには、関数expect
いくつかのmatchersの1つに沿って.ここでは、ApiserVicemockが呼び出されていないことを確認し、入力フィールドが空の文字列であることを確認しますvalue = ''
) コンポーネントが最初にレンダリングされるとき.expect(apiServiceMock).not.toHaveBeenCalled()
expect(input).toHaveValue('')
イベントを関数change
RTLのfireEvent
ユーザーの動作を複製する.このイベントは、''
to 'search'
. 他のシナリオを使用して他のシナリオを複製することができますfireEvent
メソッドclick()
, mouseOver()
. ジェストadvanceTimersByTime
メソッドは、600 msでmockタイマーを前進させるために呼び出されます.したがって600番号は引数として渡されます.advanceTimersByTime
タイマー関数によってキューされて、与えられた時間(この場合の600 ms)以内に実行されるタスクを確実にします.fireEvent.change(input, { target: { value: 'search' } })
expect(input).toHaveValue('search')
jest.advanceTimersByTime(600)
イベントを発射した後、我々はいくつかのことが起こると期待しているapiServiceMock
関数は一度呼び出され、apiServiceMock
現在の入力値にマッチします.expect(apiServiceMock).toHaveBeenCalledWith('search')
expect(apiServiceMock).toHaveBeenCalledTimes(1)
debug()
最後にdebug
関数は、反応ツリーで何が表示されているかを調べ、テストをデバッグするのを助ける.概要
話題の詳細
jest.fn()
Work? Reference
この問題について(JESTおよび反応試験ライブラリによる反応成分試験), 我々は、より多くの情報をここで見つけました https://dev.to/jdlt/react-component-testing-with-jest-and-react-testing-library-234kテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol