6

次の Java クラスがあります。

public class A
{
    @Autowired
    private B b;
    public int aFn()
    {
        int something = b.bFn();
    }
}
public class B
{
    @Autowired
    private C c;
    public int bFn()
    {
        int something = c.cFn();
    }
}
public class C
{
    public int cFn()
    {
        return 231;
    }
}

そして、Mockito を使用して上記のコードをテストする次のテスト:

public class test
{
    @Autowired
    private A a;

    private C c;

    @Test
    public void testA()
    {
        c = mock(C.class);
        when(c.cFn(),anyInt()).thenReturn(something);
        assertEquals(0, a.aFn());
    }
}

testA をデバッグすると、モックされたものではなく、実際の c.Cfn() が実行されることがわかりました。ここで私が間違っていることはありますか? 助けてください!

4

2 に答える 2

10

まず第一に、オブジェクトの推移的な依存関係ではなく、オブジェクトの直接的な依存関係を常にモックする必要があります。したがって、A をテストするには、C ではなく B をモックする必要があります。次に、C をモックすることによって、B の単体テストを記述します。

2 つ目: 単体テストのどこにもモックを挿入していません。あなたが持っているべきものは次のとおりです。

public class Test {

    // not autowired here
    private A a;

    private B mockB;

    @Test
    public void testA() {
        mockB = mock(B.class);
        when(b.bFn(), anyInt()).thenReturn(something);

        // the missing part: injecting the mock into the tested object
        a = new A(mockB);
        // or a = new A();
        //    a.setB(mockB);

        assertEquals(0, a.aFn());
    }
}

mock(B.class) を使用すると、B のモック インスタンスが 1 つ取得されます。これは、B の他のすべてのインスタンスがモックと同じことを行うという意味ではありません。

C をモックして A をテストするのは悪い習慣です。単体テストでは、1 つのクラスを他のクラスから分離してテストする必要があります。しかし、本当にそれが必要な場合は、モック C を作成し、B を作成してその中にモック C を注入し、次に A を作成してその中に B を注入します。

A --> B --> mockC
于 2013-08-21T16:02:02.013 に答える