我有这段代码-
@Component
public class ServiceA {
@Autowired
private ServiceB serviceB;
public void someMethod() {
for(Item item : items)
serviceB.foo(item);
}
}
@Component
public class ServiceB {
@Autowired
private ServiceC serviceC;
public void foo(Item item) {
if(item.boolean())
serviceC.metA();
else
serviceC.metB()
}
}
此外,我还有一个测试班-
public serviceATest {
@Spy
@InjectMocks
private ServiceA serviceA;
@Spy
@InjectMocks
private ServiceB serviceB;
@Mock
private ServiceC serviceC;
@BeforeClass
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public generalTest() {
serviceA.someMethod();
}
}
在这种情况下-ServiceB在ServiceA中为空,而ServiceC在ServiceB中不为空。
我希望ServiceB在ServiceA中不为空,并保持ServiceC在ServiceB中不为空。
我该怎么做才能使其正常工作?
答案 0 :(得分:1)
在这种情况下,您需要模拟在类ServiceC
中定义的ServiceB
的调用,对于其他情况,则相同
测试代码段
@Test
public generalTest1() {
Mockito.when(serviceC.metA()).thenReturn(<Whatever is the return type of foo()>);
Mockito.when(serviceC.metB()).thenReturn(<Whatever is the return type of foo()>);
serviceB.foo();
}
答案 1 :(得分:0)
对于您提供的示例,服务A方法除了调用serviceB方法外,实际上并不包含任何要测试的业务逻辑。而且由于单元测试的全部目的是测试特定类/方法的业务逻辑,所以没有测试该方法的要点,因为没有要测试的业务逻辑。
如果我们考虑您提供的模拟,则在对A类进行单元测试时,应该模拟所有在A类中引用的类。在您要测试服务A的情况下,需要模拟serviceB,因为它正在被模拟。直接在A类中提及。但是,由于服务C在A中没有被引用,因此无需对其进行模拟。 现在,在测试方法时,我们将模拟在其中调用的所有方法的结果。再次的目的是测试Method的业务逻辑是否按预期工作。
要测试的课程带有“ InjectMocks”(在您的情况下为服务A)注释 @模拟服务A引用的对象(serviceB的对象) 以后,可以使用Mockito.mock方法模拟方法。