InjectMocks几次

时间:2019-12-29 14:35:28

标签: java unit-testing mocking

我有这段代码-

@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中不为空。

我该怎么做才能使其正常工作?

2 个答案:

答案 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方法模拟方法。