APIクライアントの単体テストを実際に行う価値はありますか?


38

これは今しばらく私を悩ませてきたものです。APIクライアントの単体テストを実際に行う価値はありますか?

petshop REST APIへの呼び出しを抽象化するための小さなクラスを作成しているとしましょう。petshopは非常に単純なAPIであり、基本的なメソッドセットがあります。

  • listProducts()
  • getProductDetails(ProductID)
  • addProduct(...)
  • removeProduct(ProductID)

これをテストするには、モックサービスを作成するか、応答をモックする必要があります。しかし、それは行き過ぎのようです。タイプミス/構文エラーによってメソッドの動作が停止しないことを確認したいのですが、リモートメソッドを呼び出す関数を作成し、それらのリモートメソッドから偽の応答を作成しているため、努力の無駄であり、実際に失敗することのない何かをテストしています。さらに悪いことに、リモートメソッドが変更された場合、本番環境の使用が失敗している間にユニットテストに合格します。

何かが足りないのか、スティックの端が間違っているのか、木の代わりに木が見えないのはかなり確かです。誰かが私を正しい軌道に乗せることができますか?


1
これが基本的なメソッドを備えた単純なAPIでなかった場合、違うと感じますか?小屋でさえ雪に立ち向かわなければなりません。
ジェフ14

回答:


31

リモートAPIクライアントの仕事は、特定の呼び出しを発行することです-これ以上でもそれ以下でもありません。したがって、テストでは、これらの呼び出しを発行することを検証する必要があります-これ以上でもそれ以下でもありません。

もちろん、APIプロバイダーが応答のセマンティクスを変更すると、システムは実稼働で失敗します。しかし、それはクライアントクラスのせいではありません。それは統合テストでしか捕まえられないものです。あなたの制御下にないコードに依存することにより、内部テストを介して正確性を検証する機能を放棄しました。これはトレードオフであり、これが価格です。

ただし、別のクラスへの委任のみで構成されるクラスのテストは、複雑なエラーのリスクが比較的少ないため、優先順位が低い場合があります。しかし、それは均一なワンライナーのみで構成されるクラスに当てはまり、別のベンダーのコードを呼び出すこととは関係ありません。


うーん、同意するかどうかわかりません。foo()beforeをbar()呼び出すことをテストできますが、それはfoo()beforeを呼び出すbar()ことが正しいことを意味するわけではありません。そのような単体テストは、コードが間違っていても合格します。そして、それがクライアントのすべてである場合、foo()以前に呼び出されるかどうかを確認するモックをセットアップするbar()ことは、クライアントコードを大まかに一目で確認できる何かにとって比較的面倒です。
ドーバル14

1
add()メソッドが2つの数値を正しく加算することをテストできますが、それはアルゴリズムのこの時点で加算することが正しいことを意味するものではありませんadd()。プログラムが間違っていてもユニットテストは成功します。それ間違っている場合、あなたのlevenshteinDistance()方法は方法ではなく、非難するadd()ことです。これはまったく同じです。コードをメソッドに分離することのポイントは、常に、各メソッドが1つの事柄を正しく処理することだけを気にする必要があるということです。
キリアンフォス

3
今、私たちが意見が合わないところがわかりました!外部のペットショップに依存している場合、これはシステムがHTTP境界で終了することを意味します。したがって、発行されたREST呼び出し出力であり、テストの対象となります。このモジュールのペットショップの部分を考慮すると、はい、発行された呼び出しのパターンは実装の詳細であり、単体テストではそれらについて規定するビジネスはありません。
キリアンフォス

2
「したがって、そのテストは、それらの呼び出しを発行することを検証する必要があります」それは私が見逃していた視点だと思います。ありがとう!
フィリップBオルダム14

1
例えば、私のユニットテストは、特定のパラメーターが与えられた場合、それが実行しようとしているリクエストのボディが正しいかどうかをチェックできますか?
マリアイネスパルニサリ

9

短い答え:

すべてのメソッドは単体テストする必要があります。

長い答え:

はい。それは価値があります。

これらは、API呼び出しメソッドの単体テストでテストする必要があるものです。

  • 整形式または正しいパラメーターをAPI呼び出しに渡していること。
  • たとえば、APIが空の文字列を返す場合、メソッドがデフォルト値を返す必要がある場合(例)
  • API呼び出しでエラーが発生したときに呼び出し元のメソッドが正しく動作すること

これらは、呼び出されたメソッドが行うことであり、APIサービスをモックすることで分離でき、APIを呼び出すクライアントコードのエラーによってエラーが発生しないことを保証します。


「モックされているかどうか」と言いますが、実際のAPIに対してテストしても大丈夫ですか?単体テストのように見えても、統合テストと呼べますか?または、これを呼び出す別のものがありますか?私は私のAPIラッパーが、それはそれは...何とか、ありません言うんことをテストしてみたい
ダンRosenstark

1
@DanRosenstark APIサービスがモックされていない場合、それは統合テストだと思います。
Tulainsコルドバ

APIを実際に呼び出したときに適切にデータを取得しているかどうかは、5秒でわかりませんか?APIモックは実際の呼び出しではないため、失敗する唯一の方法は、APIを変更した場合です...その場合、モックテストは合格しますが、実際の呼び出しは失敗します。無意味なようです
MattE

5

これらは、制限された統合テストのように、システムの入出力をテストしているため、単体テストではありません。

「努力の無駄のようであり、実際に失敗しないものをテストしている」と言うときは非常に注意してください-それは失敗する可能性があり、失敗します、おそらくあなたが予想できない方法で失敗します、テストを実施していない場合、失敗はさらに悪化します。

ここであなたが犯している間違いは、車輪の発明に関係しています:リモートサービスとAPIへの呼び出しは非常に一般的なシナリオであるため、テストに役立ついくつかの非常に優れたツールがあります。前回、リモートサービスに接続するアプリケーションで作業していたときに、SoapUIを使用しましたサービスを見て、そのサービスに対して模擬呼び出しを行うか、サーバーのローカルコピーとして動作することができます。サーバーのテストコールを行い、要求と応答を追跡できます。セットアップには数分かかり、リモートインターフェイスが変更された場合も同様に非常に迅速に更新できました。私はRESTシナリオでは使用していませんが、それがうまく機能しない場合(またはおそらくより良いツールが存在するときに誰かがこの答えを読んでいる場合)でも、モックアップできるツールを見つけることができるはずですあなたのためのサービスであり、コードを展開するときが来たら、あなたはあなたがしたことをうれしく思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.