反応成分模擬の基本形
14379 ワード
私は、なぜmockingが役に立つかについて見ました.
この部分では、私は反応の模擬コンポーネントの基本的な形式をカバーします.
このポストのすべてのコードサンプルは、以下のレポで利用できます.
作業中のコンポーネントをもう一度見てみましょう.
こちらです
我々はいくつかのテストを書くつもりです
重要な点は、我々はスタブアウトです
これがモックです
モックは MOCKがモジュールレベルであるので、あなたがモックしているどんなコンポーネントもそれ自身のモジュールである必要があります. への呼び出し パラメータ スタブの実装は常にそれらを作ることができるように単純である必要があります.反応するコンポーネントのために の属性があります 使用試験に反対する反応テストライブラリ The これは、反応成分の塊の基本的な形です.私のおかあさんの90 %(またはそれ以上)は、これを見ます.他の10 %は、後のポストで見る若干の小さい追加をします.
そのモックーで、いくつかのテストを書きましょう
言い換えれば、我々は実際に実際にレンダリングしたことを確認します
私が使った通知
実際、テストの模擬は私が使用する唯一の時間です
我々が得るのは、モックオブジェクトを構築する一貫した方法を持つ能力です.
ですから、
期待が失敗し、例外が発生するかどうかの選択を考えてみると、テストランナーにとって意味があるので、いつか期待を選べます.
番目のテストでは、右小道具が渡されたチェックが必要です
反応があなたの構成要素をインスタンス化するとき、それは単に最初のパラメタとしてのプロップと第2のパラメタとしてrefを持つ定義された機能を呼び出しています.番目のパラメータは通常重要ではありません.
JSXステートメント
しかし、それは我々にとって有用でない幻の第2のパラメータも含みます.
反応があなたの構成要素に渡す第2のパラメタは、インスタンスRefです.それは通常我々のテストに重要でありません
あなたが取り除くことを望むならば
まれに、モックオフしたコンポーネントは、パラメータを取ることはありません.使えます
つのテストと1つの模擬を書きました.ここで私たちがこれまで明らかにした重要な教訓があります. あなたのモックはスパイを使用する必要があります また、 この属性の値は、慣習化されたコンポーネントの名前です.だから すべての模擬は少なくとも2つのテストを必要とします:最初のチェックはDOMに存在し、2番目のテストは正しい小道具で呼び出されます.
私は少なくとも2つのテストを必要とする2、3回言及しました.しかし、なぜですか?
最初のテストを行わなかった場合、DOMの存在を確認するには、単純な関数呼び出しを使用して2番目のテストパスを作成できます.
さて、あなたが最初のテストをしたが、2番目ではない場合はどうですか?
次のようにしてください.
実際のソリューションを取得するには、両方のテストが必要です.
これは、エンドツーエンドテストと単体テストの重要な違いです:ユニットテストはエンドツーエンドテストがない傾向にある方法で防御です.
キーポイント:常にあなたのテストを渡すために最も簡単な生産コードを書く.そうすることで、すべてのシナリオをカバーするテストスイートを書くのに役立ちます.
それは模擬コンポーネントの基礎をカバーします.次の部分で、我々は見ます.
この部分では、私は反応の模擬コンポーネントの基本的な形式をカバーします.
このポストのすべてのコードサンプルは、以下のレポで利用できます.
dirv / コンポーネントをmocking反応
コンポーネントをモックアップする方法の例
作業中のコンポーネントをもう一度見てみましょう.
BlogPage
and PostContent
.こちらです
BlogPage
:const getPostIdFromUrl = url =>
url.substr(url.lastIndexOf("/") + 1)
export const BlogPage = ({ url }) => {
const id = getPostIdFromUrl(url)
return (
<PostContent id={id} />
)
}
BlogPage
ショー以外のことはしないPostContent
. しかし、それは我々が興味を持っている機能の小さな部分を持っていますurl
prop値必須の投稿を引き出すid
.PostContent
もう少し複雑になっています.ブラウザの内蔵を呼び出しますfetch
ブログ投稿のテキストをURLで取得する関数/post?id=${id}
, どこid
支柱はそれに渡されます.export const PostContent = ({ id }) => {
const [ text, setText ] = useState("")
useEffect(() => {
fetchPostContent(id)
}, [id])
const fetchPostContent = async () => {
const result = await fetch(`/post?id=${id}`)
if (result.ok) {
setText(await result.text())
}
}
return <p>{text}</p>
}
実際、何PostContent
我々は再びそれを見に行かないので、それは重要ではありませんか!我々はいくつかのテストを書くつもりです
BlogPage
テストファイルでBlogPage.test.js
. それをするには、我々はモックアウトするPostContent
そのため、実装を心配する必要はありません.重要な点は、我々はスタブアウトです
PostContent
それで我々BlogPage.test.js
テストスイートはそれが何であるかから遮蔽されるPostContent
です.これがモックです
PostContent
:import { PostContent } from "../src/PostContent"
jest.mock("../src/PostContent", () => ({
PostContent: jest.fn(() => (
<div data-testid="PostContent" />
))
}))
これを壊しましょう.jest.mock
. これは対応するインポートをミラーする必要があります.そのように呼び出しを上げますimport
置換できます.Jestはモジュール全体を新しく定義したモジュールに置き換えます.だからこの場合、我々は全体を嘲笑している../src/PostContent
ファイル.jest.fn
スパイを生成します:それが呼ばれるとき、そして、どんなパラメタで記録するオブジェクト.次に、toHaveBeenCalled
and toHaveBeenCalledWith
マッチャーjest.fn
関数が呼び出されたときに返されるスタブ値を定義します.div
—これは間違いなくHTML要素の意味の最小量です!data-testid
この特定の要素をDOMに保持するために使用します.data-testid
テストランナーがあなたのソフトウェアを使っている本当の人であるかのように、あなたがあなたのテストを扱うことを望むので、可能であるところ.しかし、モックのために、私はその指導を無視します.data-testid
valueコンポーネントの名前にマッチします.この場合、それはPostContent
. これは私が私のすべての塊のために続く標準的な慣例です.そのモックーで、いくつかのテストを書きましょう
BlogPage
.モンクされたコンポーネントがDOMでレンダリングされることを確認する
describe("BlogPage", () => {
it("renders a PostContent", () => {
render(<BlogPage url="http://example.com/blog/my-web-page" />)
expect(screen.queryByTestId("PostContent"))
.toBeInTheDocument()
})
})
このテストは、コンポーネントのMCKを使用するときに常に必要な2つのテストの最初です.The screen.queryByTestId
現在のDOM内のコンポーネントを検索するdata-testid
値PostContent
.言い換えれば、我々は実際に実際にレンダリングしたことを確認します
PostContent
コンポーネント.QuerybyStatdの責任ある使用法
私が使った通知
queryByTestId
. 反応テストライブラリは、2つのアカウントでこの機能からあなたをプッシュしようとします:まず、それはあなたが使用したいgetBy
賛成にqueryBy
, そして第二に、既に述べたように、テストIDで検索したくない.実際、テストの模擬は私が使用する唯一の時間です
queryByTestId
. 私は、私が使用を避けることができなかった時間を考えることができませんTestId
非モンク部品のバリアントしかし、それが正確にその技術的な詳細は、我々はチェックしたいのです.ユーザーはこのコンポーネントを見ることはありません、それは純粋に我々のテストのためです.我々が得るのは、モックオブジェクトを構築する一貫した方法を持つ能力です.
<div data-testid="ComponentName" />
すべてのmockオブジェクトに使用できる標準パターンです.Getby *対Queryby
getBy
variantは要素にマッチできない場合に例外を送出します.私の意見では、呼び出しが予想の一部でないとき、これは適切なだけです.ですから、
expect(screen.getByTestId("PostContent"))
.toBeInTheDocument()
あなたがレンダリングしなかったならば<PostContent />
このテストは1からの例外で爆発するだろうgetByTestId
. 期待は全く実行されません!期待が失敗し、例外が発生するかどうかの選択を考えてみると、テストランナーにとって意味があるので、いつか期待を選べます.
Unit tests, and in particular when TDD style tests, are very often about the presence of elements. For these tests I find the
queryBy
much more to my liking.
模擬が正しい小道具を通過することを確かめる
番目のテストでは、右小道具が渡されたチェックが必要です
PostContent
.it("constructs a PostContent with an id prop created from the url", () => {
const postId = "my-amazing-post"
render(<BlogPage url={`http://example.com/blog/${postId}`} />)
expect(PostContent).toHaveBeenCalledWith(
{ id: postId },
expect.anything())
})
これは標準的なjest matchersを使用します.toHaveBeenCalledWith
それを保証するPostContent
関数は、期待しているパラメータで呼び出されました.反応があなたの構成要素をインスタンス化するとき、それは単に最初のパラメタとしてのプロップと第2のパラメタとしてrefを持つ定義された機能を呼び出しています.番目のパラメータは通常重要ではありません.
JSXステートメント
<PostContent id="my-amazing-post" />
関数コールの結果PostContent({ id: "my-amazing-post" })
.しかし、それは我々にとって有用でない幻の第2のパラメータも含みます.
期待を使う2番目のパラメータに対しては何かを指定します。
反応があなたの構成要素に渡す第2のパラメタは、インスタンスRefです.それは通常我々のテストに重要でありません
expect.anything()
あなたがその価値に興味がないことを意味します.あなたが取り除くことを望むならば
expect.anything()
コールは、あなたのためにそれを渡す独自のジェスマッチを書くことができます.プロップを渡していない場合は、
まれに、モックオフしたコンポーネントは、パラメータを取ることはありません.使えます
toHaveBeenCalled
の簡単なバージョンとしてtoHaveBeenCalledWith
.部品塊の基本ルールの理解
つのテストと1つの模擬を書きました.ここで私たちがこれまで明らかにした重要な教訓があります.
jest.fn
また、可能な限り単純なコンポーネントの返り値を持ちます.<div />
data-testid
属性を使用すると、DOM内の要素を直接指定できます.PostContent
コンポーネントの値は<div data-testid="PostContent" />
. なぜ2つのテスト?
私は少なくとも2つのテストを必要とする2、3回言及しました.しかし、なぜですか?
最初のテストを行わなかった場合、DOMの存在を確認するには、単純な関数呼び出しを使用して2番目のテストパスを作成できます.
export const BlogPost = () => {
PostContent({ id: "my-awesome-post" })
return null
}
なぜ、あなたがこれをしたいと思うかは、他の全部のブログ柱の主題です、しかし、ここでは、短いバージョンです:一般に、我々はJSX声明より単純である関数呼び出しを考慮します.厳密なテスト原理を使用しているときは、常にテストパスを作成するために最も単純なコードを記述する必要があります.さて、あなたが最初のテストをしたが、2番目ではない場合はどうですか?
次のようにしてください.
export const BlogPost = () => (
<PostContent />
)
繰り返しますが、これはテストパスを作る最も簡単な生産コードです.実際のソリューションを取得するには、両方のテストが必要です.
これは、エンドツーエンドテストと単体テストの重要な違いです:ユニットテストはエンドツーエンドテストがない傾向にある方法で防御です.
キーポイント:常にあなたのテストを渡すために最も簡単な生産コードを書く.そうすることで、すべてのシナリオをカバーするテストスイートを書くのに役立ちます.
それは模擬コンポーネントの基礎をカバーします.次の部分で、我々は見ます.
Reference
この問題について(反応成分模擬の基本形), 我々は、より多くの情報をここで見つけました https://dev.to/d_ir/the-basic-form-for-react-component-mocks-g5テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol