Java Mockito - 如何测试在同一个类中调用方法的方法以及从其他类调用方法?

时间:2016-06-10 09:58:29

标签: unit-testing junit mocking mockito spy

我有这样的代码结构。 methodToTest中的方法ClassA正在调用ClassA中的方法以及ClassB中的方法

public class ClassA {
    @Autowired
    ClassB classB;

    public void methodToTest() {
        Object c = methodInA();
        Object d = classB.methodInB(c);
    }

    public Object methodInA() {
        //do something
    }
}

public class ClassB {
    public Object methodInB(Object obj) {
        //do something
    }
}

我试图模拟两个电话,即拨打methodInAmethodInB

以下是单元测试代码

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class ClassATest {
    @InjectMocks
    ClassA classA;

    @Mock
    ClassB classB;

    @Spy
    ClassA classASpy;

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

    //Test method in ClassA
    @Test
    public void testMethodInA() {
        Object mockObjA = mock(Object.class);
        Object mockObjB = mock(Object.class);

        doReturn(mockObjA).when(classASpy).methodInA();
        when(classB.methodInB(mockObjA)).thenReturn(mockObjB);

        classA.methodToTest();

        //assertions
    }

}

在运行测试时,Object c为空但我希望它等于mockObjA

我也试过了classASpy.methodToTest()来自测试的调用。但是,它会在NullPointerException中的Object d = classB.methodInB(c)methodToTest()处提供。{/ p>

测试此类场景的正确方法是什么?

1 个答案:

答案 0 :(得分:2)

当您调用methodToTest时,您正在测试单位ClassA。通过模拟该单元的某些东西来改变被测单元是没有多大意义的。因为那时你会测试一些与ClassA完全不同的东西。

您应该做的是测试使用正确的参数调用classB.methodInB。您可以使用ArgumentCaptor作为调用classB.methodInB的参数。

ArgumentCaptor<Object > argument = ArgumentCaptor.forClass(Object .class);
verify(mockObjB).methodInB(argument.capture());
Object capturedArgument = argument.getValue();

然后在capturedArgument上进行断言,验证ClassA.methodInA是否正常工作。