3

SpringinActionの本を読み始めました。

私は自分の疑問が疑わしいと思うJUnitの知識を持っていません。

作成者が参照し、テストが難しいと言っているコードフラグメントがあります。

package com.springinaction.knights;

public classDamselRescuingKnight implements Knight {

    private RescueDamselQuest quest;

    public DamselRescuingKnight() {
       quest = new RescueDamselQuest();
    }

    public voidembarkOnQuest() throwsQuestException {
       quest.embark();
    }
}

著者は次のように述べています。

DamselRescuingKnightの単体テストを作成するのは非常に難しいでしょう。このようなテストでは、騎士のembarkOnQuest()が呼び出されたときに、クエストのembark()メソッドが呼び出されたことを表明できるようにする必要があります。しかし、ここでそれを達成する明確な方法はありません。残念ながら、DamselRescuingKnightはテストされていません。

これは、作者が何を意味するのでしょうか。

ここでコードをテストするのが難しいのはなぜですか?

4

4 に答える 4

8

私の最初の考えは、「RescureDamselQuest」オブジェクトがコンストラクターで初期化されるため、テストが難しいということです。これにより、たとえばモックオブジェクトを挿入することが困難になります。モックオブジェクトは、embark()メソッドが「RescueDamselQuest」オブジェクトで呼び出されることをテストするのに役立ちます。

これを解決するためのより良い方法は、コンストラクターにパラメーターを含めることです(通常、私はこのメソッドを好みます)。

public DamselRescuingKnight(RescueDamselQuest quest){
   this.quest = quest;
}

または、セッターを追加します。

public void setDamselRescuingKnight(RescueDamselQuest quest){
   this.quest = quest;
}
于 2013-03-13T13:44:58.037 に答える
2

私が挙げる一般的な例は、ファイルを開いて解析し、データクラスを取得したいと考えていることです。ほとんどは次のようなことをします:

Data openAndParse(String filename) {
  ...openFile
  ...parse
}

このようにすることで、ファイルを開く方法と解析が高度に結合され、テストが困難になります。オープンと解析に問題がある場合、それは解析とオープンのどちらにありますか?

JUnitテストを作成することにより、簡単にするために、次のようなことを強制されます...

BufferedReader openFile(String filename) {
  ...open file and return reader
}

Data parse(BufferedReader input) {
  ...parse and return data
}

JUnitは、よりまとまりのあるソリューションに導きます。JUnitテストは、文字列を作成し、StringReaderを作成してから、BufferedReaderを作成するだけで記述できます。何だと思いますか?同様に、解析を使用して、ファイルだけでなくさまざまなソースからの入力を受け入れることができます。

于 2013-03-13T14:00:06.280 に答える
0

クエストの実装を交換できないため、テストは困難です。バイトコードを変更しないと、embarkが呼び出されたかどうかを確認する簡単な方法はありません。

コンストラクターまたはセッターでクエストの実装を設定できる場合は、乗船の呼び出しをスパイできる実装を渡すことができます。

于 2013-03-13T13:45:46.487 に答える
0

テストするクラスのフィールドとメソッドのアクセシビリティを向上させる必要があります。たとえば、パッケージプライベート(デフォルト)のメソッドをテストしている場合、通常は異なるパッケージに含まれているテストケースでは、このメソッドをテストできません。したがって、メソッドをテストするには、フィールドのアクセシビリティを変更することをお勧めします。RescueDamselQuestフィールドのアクセシビリティをプライベートからデフォルトに変更することにより、DIを使用していないDamselRescuingKnightクラスをテストできます。次に、mockitoを使用してテストケースを作成します。これがテストケースのコードです

@Test
public void knightShouldEmbarkOnQuest() throws QuestException {


    DamselRescuingKnight knight = new DamselRescuingKnight();
    RescueDamselQuest quest = mock(RescueDamselQuest.class);
    knight.quest = quest;
    knight.embarkOnQuest();
    verify(quest, times(1)).embark();
}

そして、DamselRescuingKnightクラスでプライベートアクセシビリティを削除するために変更された行

RescueDamselQuest quest;
于 2019-03-28T09:50:51.927 に答える