问题描述
我有一个服务,它有一个我想要模拟的 DataProvider
。
问题:服务使用 @postconstruct
中的数据提供者。但是当我使用 @MockBean
时,@postconstruct
中不存在模拟值。
我能做什么?
@Service
public class MyService {
private List<Object> data;
@Autowired
private DataProvider dataProvider;
@postconstruct
public void initData() {
data = dataProvider.getData();
}
public void run() {
System.out.println(data); //always null in tests
}
}
@SpringBoottest
public class Test {
@MockBean
private DataProvider dataProvider;
@Test
public void test() {
when(dataProvider.getData()).thenReturn(mockedobjects);
//dataProvider.init(); //this fixes it,but feels wrong
service.run();
}
}
解决方法
恕我直言,单元测试 MyService
将是这种特定场景的更好解决方案(在这种情况下,我不会觉得手动调用 initService
有错),但如果您坚持...>
您可以简单地覆盖此特定测试的 DataProvider
bean 定义并预先模拟它,例如:
@SpringBootTest(classes = {MyApplication.class,Test.TestContext.class})
public class Test {
@Test
public void test() {
service.run();
}
@Configuration
static class TestContext {
@Primary
public DataProvider dataProvider() {
var result = Mockito.mock(DataProvider.class);
when(result.getData()).thenReturn(mockedObjects);
return result;
}
}
}
您可能需要将 spring.main.allow-bean-definition-overriding
设置为 true
才能使上述操作生效。