我有一个控制器类:
Timer.scheduledTimer(withTimeInterval: intervalInSec, repeats: true) {
一个提供IProcessor不同实例的Factory类:
public class Controller {
private final IProcessor processor;
public Controller (final ProcessorFactory factory) {
this.processor = factory.getInstance();
}
}
在使用Junit5的模拟测试类中,我无法实例化@Component
public class ProcessorFactory {
private final Dep1 dep1;
private final Dep2 dep2;
public ProcessorFactory (final Dep1 dep1,
final Dep2 dep2) {
this.dep1= dep1;
this.dep2= dep2;
}
public IProcessor getInstance() {
if (...) {
return new ProcessorA(dep1, dep2);
}
return new ProcessorB(dep1, dep2);
}
}
成员,并且为null:
IProcessor
我不确定我是否正确使用了MockBean。基本上我想同时模拟Factory和Processor。
答案 0 :(得分:2)
由于您需要在Spring上下文初始化期间(在getInstance()
的构造函数中)调用模拟方法(Controller
),因此需要以不同的方式模拟所述方法。不仅要提供模拟的bean作为现有对象,还应该定义其模拟行为。
另外,IProcessor
实现未配置为Spring Bean,因此Spring不会注入它们-ProcessorFactory
显式调用new
并在不涉及Spring的情况下创建对象。
我已经创建了一个简单的项目来重现您的问题并提供解决方案-如果您想检查整个程序是否正常工作,可以找到here on GitHub,但这是最重要的测试代码段(我ve简化了方法):
@WebMvcTest(Controller.class)
class ControllerTest {
private static final IProcessor PROCESSOR = mock(IProcessor.class);
@TestConfiguration
static class InnerConfiguration {
@Bean
ProcessorFactory processorFactory() {
ProcessorFactory processorFactory = mock(ProcessorFactory.class);
when(processorFactory.getInstance())
.thenReturn(PROCESSOR);
return processorFactory;
}
}
@Autowired
private MockMvc mockMvc;
@Test
void test1() throws Exception {
String result = "this is a test";
when(PROCESSOR.process(any()))
.thenReturn(result);
mockMvc.perform(post("/test/test")
.contentType(MediaType.APPLICATION_JSON)
.content("{}"))
.andDo(print())
.andExpect(status().is2xxSuccessful())
.andExpect(content().string(result));
}
}