web-dev-qa-db-ja.com

Mockitoを使用してパラメーター化されたコンストラクターのスパイを作成できないのはなぜですか

私のコードにはパラメーター化されたコンストラクターしかなく、それを介して注入する必要があります。

パラメーター化されたコンストラクターをスパイして、モックオブジェクトをjunitの依存関係として挿入します。

public RegDao(){
 //original object instantiation here
Notification ....
EntryService .....
}

public RegDao(Notification notification , EntryService entry) {
 // initialize here
}

we have something like below : 
RegDao dao = Mockito.spy(RegDao.class);

しかし、モックされたオブジェクトをコンストラクタに挿入してスパイできるものはありますか?.

14
Pradeep

それを行うには、junitでパラメーター化されたコンストラクターを使用してメインクラスをインスタンス化し、それからスパイを作成します。

メインクラスがAであるとします。ここで、BおよびCはその依存関係です。

public class A {

    private B b;

    private C c;

    public A(B b,C c)
    {
        this.b=b;
        this.c=c;
    }

    void method() {
        System.out.println("A's method called");
        b.method();
        c.method();
        System.out.println(method2());

    }

    protected int method2() {
        return 10;
    }
}

次に、以下のようにパラメーター化されたクラスを使用して、このためのjunitを記述できます。

@RunWith(MockitoJUnitRunner.class)
public class ATest {

    A a;

    @Mock
    B b;

    @Mock
    C c;

    @Test
    public void test() {
        a=new A(b, c);
        A spyA=Mockito.spy(a);

        doReturn(20).when(spyA).method2();

        spyA.method();
    }
}

テストクラスの出力

A's method called
20
  1. ここでBCは、パラメータ化されたコンストラクタを使用してクラスAに注入したモックオブジェクトです。
  2. 次に、spyというAというspyAを作成しました。
  3. spyが実際に機能しているかどうかは、プロテクトメソッドの戻り値を変更することで確認しましたmethod2クラスAspyAspyの実際のAでなかった場合は不可能でした。
20
Dhawal Kapil

依存性注入ソリューションがない可能性があります。 Mockitoは、DIを使用してモックを注入するのに最適です。たとえば、CDIを使用し、NotificationおよびEntryServiceメンバーに@Injectを注釈として付け、テストで@Mocksを両方に宣言し、Mockitoにそれらを挿入させることができます。テスト用のRegDao.

これは、実行しようとしているテストのモックアップです。

import static org.junit.Assert.assertEquals;

import javax.inject.Inject;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class MockitoSpyInjection {
    static class Notification { }
    static class EntryService { }
    static class RegDao {
        @Inject
        Notification foo;

        @Inject
        EntryService  bar;

        public RegDao() {
        }

        public RegDao(Notification foo, EntryService bar) {
            this.foo = foo;
            this.bar = bar;
        }

        public Notification getFoo() {
            return foo;
        }

        public EntryService getBar() {
            return bar;
        }

    }


    @Mock
    Notification foo;

    @Mock
    EntryService bar;

    @Spy
    @InjectMocks
    RegDao dao;

    @Test
    public void test() {
        assertEquals(foo, dao.getFoo());
        assertEquals(bar, dao.getBar());
    }
}
0
Isaac Truett