2

単体テストには Android SDK と junit4 + Mockito を使用しています。アプリに次のようなクラスがあるとします。

public class Container{

  @NonNull private Set<String> values = new HashSet<>();

  public void addValue(String value) {
    values.add(value);
  }

  @NonNull
  public Set<String> getValues() {
    return values;
  }
}

また、次のような Mockito を使用した単体テストもあります。

public class ContainerTest {

  private Container container;

  @Before
  public void before() {
    container = mock(Container.class);
  }

  @Test
  public void shouldAddValue() {
    container.add("test_value");
    assertTrue(container.getValues.contains("test_value"));
  }

}

このテストは、実際には "container.add("test_value");" 行で失敗します。mock(Container.class)はフィールドが実際に null に設定されているクラスを作成するため、addValue()メソッドの values.add (value)はNPE をスローします。これを修正するためにaddValue()にnull チェックを追加することもできますが、値はすでに非 null と宣言されているため、それはばかげているように思えます。

Mockito に @NonNull アノテーションを尊重させ、フィールドを適切に初期化する方法はありますか?

4

1 に答える 1

2

Mockito の動作を定義する必要があるため、Mockito を正しい方法で使用していないと思います。

たとえば、次のようなものが必要です。

@Test
public void shouldAddValue() {
    Set<String> mySet = new HashSet<String>();
    mySet.put("test_value");

    // Mock container getValues() method to return mySet
    when(container.getValues()).thenReturn(mySet); // do import static for Mockito.when

    assertTrue(container.getValues().contains("test_value"));
}

Mockito は応答をモックするときに非常にうまく機能しますが、必要なのは Mockito にクラスを初期化させることであり、これは明らかに Mockito の目標ではありません。

したがって、Container オブジェクトをテストする場合は、Container 自体をモックする必要はなく、次のようにすることができます。

public class ContainerTest {

    private Container container;

    @Before
    public void before() {
        container = new Container(); // Initialize container
    }

    @Test
    public void shouldAddValue() {
        container.addValue("test_value");
        assertTrue(container.getValues().contains("test_value"));
    }

}
于 2015-11-09T20:00:37.377 に答える