16

私はSpring Cloudのeurekaとfeignを使用して、いくつかのサービス間で通信しています(AとBとしましょう)。ここで、単一のサービス (A) のサービス レイヤーを単体テストしたいと思います。問題は、このサービス (A) が偽のクライアントを使用して、他のサービス (B) の情報を要求していることです。

特別な構成なしで単体テストを実行すると、次の例外がスローされます: java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: service-b=> しかし、サーバーを実行したくありません。

私の質問は次のとおりです:偽のクライアントをモックする方法はありますか?それで、eureka インスタンスとサービス (B) を実行せずにサービス (A) を単体テストできますか?

編集:偽のクライアント用のスタブを作成しました。スタブは、テスト内でスタブをインスタンス化するスプリングを強制するプライマリ コンポーネントとしてマークされています。
これが私が思いついた解決策です。

//the feign client
@FeignClient("user") 
public interface UserClient { 
    UserEntity getUser(); 
}

//the implementation i use for the tests 
@Component 
@Primary //mark as primary implementation
public class UserClientTestImpl implements UserClient { 
    @Override public UserEntity getUser() { 
        return someKindOfUser; 
    } 
}
4

3 に答える 3

8

問題は...あなたも嘲笑する必要がありますか? 「単体テストの一部であってはならない」ものに対する最初の解決策として「モック」に言及する人をよく見かけます。モッキングはテクニックであり、すべての解決策ではありません。(ここを参照)。

まだコードの初期段階にある場合は、Feign Client の具体的なインスタンスに依存するのではなく、リファクタリングして別のものを使用してください。インターフェイス、抽象クラス、特性、または必要なものを使用できます。オブジェクト自体に依存しないでください。それ以外の場合は、「モック」する必要があります。

public interface IWebClient {
  public String get(...);
  public String post(...);
} 

質問に対して:しかし、まったく同じことを行う他のコードがあります(それがFeignの具体的なインスタンスにあることを除いて)、次に何をしますか?さて、機能テストを作成し、ローカルでセットアップできる Web サーバーのインスタンスを呼び出すか、または回答の 1 つで Marcin Grzejszczak が述べたように、Wiremock を使用できます。

public class FeignClientWrapper implements IWebClient {
  private feign = something

  public String get() {
    feign.get( ... ) 
  }

  public String post() {
    feign.post( ... ) 
  }
} 

単体テストは、アルゴリズム、if/else、ループ、つまりユニットの動作をテストするために使用されます。モックを適合させるためにコードを書かないでください - それは逆でなければなりません: あなたのコードはより少ない依存性を持つべきであり、動作を検証する必要がある場合にのみモックするべきです (そうでなければ、スタブまたは偽のオブジェクトを使用することができます):動作を確認する必要がありますか?コードで特定のメソッドが呼び出されることをテストする必要がありますか? または、特定のメソッドが X、Y、および Z で 3 回続けて呼び出されることはありますか? そうですね、嘲笑は大丈夫です。

それ以外の場合は、偽のオブジェクトを使用します。必要なのは、呼び出し/応答と、場合によってはステータス コードだけをテストすることです。おそらく必要なのは、コードがさまざまな出力 (たとえば、フィールド「エラー」が JSON 応答に存在するかどうか) にどのように反応するかをテストすることだけです。さまざまなステータス コード (クライアントのドキュメントが正しいと仮定して: GET の場合は 200 OK、201 の場合) POST 時など)。

于 2015-12-21T14:24:28.490 に答える