6

JUnit と Mockito を使用していくつかのクラスをテストしています。クラス自体は、別のクラスからオブジェクトを作成します。testList というリスト。ここに私のコード:

public class A {
       private List<B> bList;

       //returns the bList
       public List<B> getBList() {
          return bList;
       }

       //checks the status by calling getStatus in class B
       public Status getStatus() {
          //status is an enum consists of PASSED and FAILED
          Status finalStatus = Status.PASSED;
          for (B be : this.getTestList()) {
             if (be.getStatus() != Status.PASSED) {
                finalStatus = Status.FAILED;
                break;
             }
          }
          return status;
       }
    }


    public Class B {
       private Status status = Status.FAILED;   

       public getStatus() {
          return status;
       }

       public void setStatus(Status status) {
          this.status = status;
       }
    }

Test というクラスで getStatus メソッドと getTestList メソッドをテストする最良の方法は何でしょうか。

どうもありがとうございました....

4

3 に答える 3

4

私はあなたを見て、どうやって何かに設定されるのClassAだろうかと思いました。bList現時点では、null 以外の値にする方法はありません。つまり、getStatus毎回 null ポインター例外がスローされます。

問題は、振る舞いをテストする方法を考えるのではなく、メソッドをテストする方法を考えていることです。これが問題となる理由の 1 つは、クラスが特定の方法でアプリケーションの残りの部分に適合する必要があることです。それを確実に行うには、各メソッド内の特定の詳細ではなく、特定の動作が必要です。したがって、唯一の意味のあるテストは、動作をチェックするものです。

個々のメソッドをテストすると、実際に作成したコードに集中するようになるという事実は、おそらくもっと陰湿です。テストを書いているときにコードを見ていると、テストは自己達成的な予言になります。クラスが提供する必要がある動作のセット全体を見逃している可能性があります。しかし、クラス提供する振る舞いをテストするだけでは、決してわかりません。

では、手元の問題に戻ります。あなたのクラスが実行することが期待される 4 つ、おそらく 5 つの行動が見られます。もっとあるかもしれません - 仕様ではなくコードだけを見せてくれるとわかりにくいです。それぞれのテストを書く必要があります。各テストの名前は、テストが使用するメソッドの名前を反映するのではなく、動作を説明する必要があると強く信じています。この場合、私はこのような名前を選ぶかもしれません。

public void statusIsPassedWhenEveryTestPassed()
public void statusIsFailedWhenEveryTestFailed()
public void statusIsFailedWhenSomeTestsPassedSomeFailed()
public void statusIsPassedWhenNoTests()
public void statusIsPassedWhenTestsNotSet() // this one currently fails

各テスト内で のオブジェクトを作成し、オブジェクト内でClassAを設定するために必要なことは何でもbList行います。最後にgetStatus、戻り値が必要なものであることを呼び出してアサートします。しかし重要な点は、各テスト (最後のものを除く) が の複数のメソッドを使用することですClassA。したがって、これらは個々のメソッドのテストではありません。

于 2012-10-05T18:17:10.803 に答える
0

問題のオブジェクトに保護されたセッター(またはコンストラクターインジェクション)を提供してから、テストケース内のクラスを拡張してオブジェクトをモックするか、powermockなどを使用してみることができます。問題のオブジェクトを設定する方法を提供する必要があります。

于 2012-10-05T16:37:35.463 に答える
0

testList単体テストでどのように入力できるかによって異なります。たとえば、セッターがあれば、モック フレームワークは必要ありません。

class TestTest {

  Test test = new Test();

  @Test void should_return_failed_if_a_single_test_failed() {
     givenTestListWithOneFailedTest();
     assertThat(test.getStatus(), is(Status.FAILED))
  }

  void givenTestListWithOneFailedTest() {
     test.setTestList(createSomeTestListWithOnlyOneFailedTest());
  }

  @Test void should_return_passed_if_all_tests_passed() {
     // ...
  }

}
于 2012-10-05T16:48:25.567 に答える