Java Mockito中的嵌套方法mocking

Java Mockito中的嵌套方法mocking,java,junit,mocking,mockito,Java,Junit,Mocking,Mockito,我有以下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(); } } publi

我有以下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(),而不是模拟的。 我在这里做的有什么不对吗?
请帮忙

首先,您应该始终模拟对象的直接依赖关系,而不是其可传递依赖关系。所以您应该模拟B而不是C来测试A。然后您可以通过模拟C来为B编写单元测试

第二:在单元测试的任何地方都没有注入模拟。你应该做的是:

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的mock实例。这并不意味着B的所有其他实例都将执行mock所做的操作

模拟C来测试A是一种不好的做法:单元测试应该测试一个类而不是其他类。但是如果你真的想这样做,那么创建一个模拟C,创建一个B并在其中注入模拟C,然后创建一个a并在其中注入B

A --> B --> mockC

忘记要模拟的是直接模拟还是嵌套模拟。 从斯普林的哲学观点来思考

实际上,您想要做的是模拟一个bean

在您的例子中,必须使用@MockBean注释来模拟类c的bean

@RunWith(SpringRunner.class)
public class Test {
...
@MockBean private C c;
...
}

有关详细信息,请参阅。

我要存根c.cFn,而不是b.bFn。那该怎么办?那是个坏习惯。单元测试应该测试一个类,而不测试其他类。但是如果你想要的话,那么创建一个模拟C,创建一个B,并在其中注入模拟C,然后创建一个a,并在其中注入B<代码>A-->B-->模拟C。谢谢。请根据该修改您的答案。JB,您只讨论了单元测试,但问题从未指定测试是单元测试,或者SUT是单个类。在许多情况下,如果SUT由一个以上的类组成(在本例中为a类和B类),则进行测试是有意义的。我经常自己编写此类测试,尤其是如果B类包含有助于履行a类合同的大部分逻辑。我不同意您将其描述为“不良做法”,只要清楚哪些类包含在哪些测试中。你回答的最后一段救了你,赢得了我的选票!