我正在尝试对一个 bean 进行单元测试,并模拟另一个在构造函数中自动装配的 bean。 模拟应该在自动装配之前。
豆类:
@Component
public class ClassA {
public ClassA(ClassB b, ClassC c){
System.out.println("A->" + b.get());
}
}
@Component
public class ClassB {
public String get(){
return "foo";
}
}
@Component
public class ClassC {
public ClassC(ClassB b){
System.out.println("C->" + b.get());
}
}
测试班:
@ExtendWith(SpringExtension.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@EnableConfigurationProperties
@SpringBootTest(
classes = {
ClassA.class,
ClassC.class
})
public class SomeTest {
@MockBean
private ClassB b;
@Autowired
private ClassC c;
@Autowired
private ClassA a;
@BeforeAll
private void mockB() {
when(b.get()).thenReturn("koo");
}
@Test
void test() {
//do some test
}
}
我希望看到印刷品:
C->咕 A->咕
但得到:
C->空 A->空
我也尝试过 MockitoExtension 和 InjectMocks 。
有什么想法吗?
你可以做这个技巧:
@SpringBootTest
@ContextConfiguration(classes = SomeTest.TestConfig.class)
public class SomeTest {
@TestConfiguration
public static class TestConfig {
@MockBean
private ClassB b;
@PostConstruct
public void postConstruct() {
when(b.get()).thenReturn("koo");
}
}
@Autowired
private ClassC c;
@Autowired // you shoul use @Autowired - do not mock twice
private ClassB b;
@Autowired
private ClassA a;
@Test
void test() {
//do some test
}
}
请注意,
@MockBean
注释和mockito when-then
已移至TestConfig
。因此,如果在测试类中使用它,您应该使用 @Autowired
将 ClassB
注入到测试类中。
而且你不必使用
@ExtendWith(SpringExtension.class)
,因为@SpringBootTest
已经有了它。