我有这样的代码结构。 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
}
}
我试图模拟两个电话,即拨打methodInA
和methodInB
以下是单元测试代码
@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>
测试此类场景的正确方法是什么?
答案 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
是否正常工作。