情報は力ではない

UE4 とか Blender とか。

Mockitoの@InjectMocksは何を見てInjectするのか

InjectMocks (Mockito 2.0.36-beta API)に書いてます。
思った挙動と異なっていたので、自分のためにメモ。

次のようなSampleクラスがあったとする。

public class Sample {
    private final Hoge hoge;
    private final Fuga fuga;

    private HogeHoge hogehoge;

    public Sample(Hoge hoge, Fuga fuga) {
        this.hoge = hoge;
        this.fuga = fuga;
    }

    public Hoge getHoge() {
        return hoge;
    }

    public Fuga getFuga() {
        return fuga;
    }

    public HogeHoge getHogeHoge() {
        return hogehoge;
    }
}

このクラスに対するテストを次のように書いて実行すると、コメントの部分でAssertionErrorになる。

public class SampleTest {
    @Mock
    Hoge hoge;

    @Mock
    Fuga fuga;

    @Mock
    HogeHoge hogehoge;

    @InjectMocks
    Sample sample;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void test() {
        assertEquals(hoge, sample.getHoge());
        assertEquals(fuga, sample.getFuga());
        assertEquals(hogehoge, sample.getHogeHoge());  // ここでAssertionError
    }
}

自分は最初、MockitoAnnotations.initMocks()を呼び出すことで@Mockを指定したすべてのクラスがSampleクラスにInjectされると思ってたが、違うようだった。
そこで、この記事の最初に掲載したドキュメントを読むとConstrucor injection, Setter injection, Field injectionのいずれか"のみ"でInjectされることがわかった。
Sampleクラスの場合、Constructor injectionが行われていて、HogeクラスとFugaクラスがInjectされる。Constructor Injectionが成功したので、HogeHogeクラスはInjectionされることがないようだ。

ちゃんとドキュメントは読むべきなのだなあと改めて思った出来事だった。