英文:
how to mock private variable in RestController class
问题
以下是您要翻译的内容:
我正在使用Spring进行一些Web单元测试。是否有一种方法可以模拟在@PostConstruct
中设置的MyProcessor
实例?我尝试过使用@MockBean
,但它被设置为null,然后出现空指针异常?
我正在使用工厂根据某些布尔标志实例化MyProcessor
。但如果有其他完全不同的方法可以使我的测试更清晰,我也可以接受。
请注意,我正在使用Junit 5。
public class Controller {
private final AProcessorFactory factory;
@Value("${tt.f.processor.async}")
private boolean isAsync;
private MyProcessor myProcessor;
public Controller(final AProcessorFactory factory) {
this.factory = factory;
}
@PostConstruct
public void init() {
myProcessor = factory.getInstance(isAsync);
}
}
@WebMvcTest(Controller.class)
public class ControllerTest{
@MockBean
private MyProcessor processor;
@MockBean
private AProcessorFactory factory;
@Autowired
private MockMvc mockMvc;
@Test
public void test() throws Exception {
when(processor.process(any(Request.class), any(String.class)))
.thenReturn(new TestResponse("123", SUCCESS, "", ""));
}
}
英文:
I am doing some web unit testing with Spring. is there a way I can mock the instance of MyProcessor
which get set in @PostConstruct
? I tried with @MockBean
but it gets set as null and getting null pointer exception?
I am using a factory to instantiate MyProcessor
based on some boolean flag. But if there is a different approach altogether that would make my test cleaner, I am open to ideas.
Please Note I am using Junit 5.
public class Controller {
private final AProcessorFactory factory;
@Value("${tt.f.processor.async}")
private boolean isAsync;
private MyProcessor myProcessor;
public Controller(final AProcessorFactory factory) {
this.factory= factory;
}
@PostConstruct
public void init() {
myProcessor = factory.getInstance(isAsync);
}
}
@WebMvcTest(Controller.class)
public class ControllerTest{
@MockBean
private MyProcessor processor;
@MockBean
private AProcessorFactory factory;
@Autowired
private MockMvc mockMvc;
@Test
public void test() throws Exception {
when(processor.process(any(Request.class), any(String.class)))
.thenReturn(new TestResponse("123", SUCCESS, "", ""));
}
答案1
得分: 1
看起来你的 myProcessor
实际上是由你的 AProcessorFactory
在 PostConstruct
的 init()
方法中构建的。
你需要为你的 AProcessorFactory
模拟提供一种行为。
首先,你可能会想在构造函数中设置你的 myProcessor
,因为 @PostConstruct
的 init()
方法没有特殊的上下文加载逻辑。
public class Controller {
@Value("${tt.f.processor.async}")
private boolean isAsync;
private MyProcessor myProcessor;
public Controller(final AProcessorFactory factory) {
this.myProcessor = factory.getInstance(isAsync);
}
}
你可以在测试的 @Before
步骤中指定这一点。
@MockBean
private AProcessorFactory factory;
@Before
public void setUp() {
when(processor.process(any(Request.class), any(String.class)))
.thenReturn(new TestResponse("123", SUCCESS, "", ""));
when(factory.getInstance(any())).thenReturn(processor);
}
Spring 将会注册你的 AProcessorFactory
模拟,并加载适当的行为。
英文:
It looks like your myProcessor
is actually built by your AProcessorFactory
in a PostConstruct init() method.
You'll want to provide a behavior for your AProcessorFactory
mock.
First, you would probably want to set up your myProcessor
in your constructor as the @PostConstruct
init()
method has no special context loading logic with it.
public class Controller {
@Value("${tt.f.processor.async}")
private boolean isAsync;
private MyProcessor myProcessor;
public Controller(final AProcessorFactory factory) {
this.myProcessor = factory.getInstance(isAsync);
}
}
You can specify this in a @Before
step in your test.
@MockBean
private AProcessorFactory factory;
@Before
public void setUp() {
when(processor.process(any(Request.class), any(String.class)))
.thenReturn(new TestResponse("123", SUCCESS, "", ""));
when(factory.getInstance(any())).thenReturn(processor)
}
Spring will register your AProcessorFactory mock that has been loaded with the appropriate behaviors.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论