如何在RestController类中模拟私有变量

huangapple go评论86阅读模式
英文:

how to mock private variable in RestController class

问题

以下是您要翻译的内容:

我正在使用Spring进行一些Web单元测试。是否有一种方法可以模拟在@PostConstruct中设置的MyProcessor实例?我尝试过使用@MockBean,但它被设置为null,然后出现空指针异常?

我正在使用工厂根据某些布尔标志实例化MyProcessor。但如果有其他完全不同的方法可以使我的测试更清晰,我也可以接受。

请注意,我正在使用Junit 5。

  1. public class Controller {
  2. private final AProcessorFactory factory;
  3. @Value("${tt.f.processor.async}")
  4. private boolean isAsync;
  5. private MyProcessor myProcessor;
  6. public Controller(final AProcessorFactory factory) {
  7. this.factory = factory;
  8. }
  9. @PostConstruct
  10. public void init() {
  11. myProcessor = factory.getInstance(isAsync);
  12. }
  13. }
  14. @WebMvcTest(Controller.class)
  15. public class ControllerTest{
  16. @MockBean
  17. private MyProcessor processor;
  18. @MockBean
  19. private AProcessorFactory factory;
  20. @Autowired
  21. private MockMvc mockMvc;
  22. @Test
  23. public void test() throws Exception {
  24. when(processor.process(any(Request.class), any(String.class)))
  25. .thenReturn(new TestResponse("123", SUCCESS, "", ""));
  26. }
  27. }
英文:

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.

  1. public class Controller {
  2. private final AProcessorFactory factory;
  3. @Value("${tt.f.processor.async}")
  4. private boolean isAsync;
  5. private MyProcessor myProcessor;
  6. public Controller(final AProcessorFactory factory) {
  7. this.factory= factory;
  8. }
  9. @PostConstruct
  10. public void init() {
  11. myProcessor = factory.getInstance(isAsync);
  12. }
  13. }
  14. @WebMvcTest(Controller.class)
  15. public class ControllerTest{
  16. @MockBean
  17. private MyProcessor processor;
  18. @MockBean
  19. private AProcessorFactory factory;
  20. @Autowired
  21. private MockMvc mockMvc;
  22. @Test
  23. public void test() throws Exception {
  24. when(processor.process(any(Request.class), any(String.class)))
  25. .thenReturn(new TestResponse("123", SUCCESS, "", ""));
  26. }

答案1

得分: 1

看起来你的 myProcessor 实际上是由你的 AProcessorFactoryPostConstructinit() 方法中构建的。

你需要为你的 AProcessorFactory 模拟提供一种行为。

首先,你可能会想在构造函数中设置你的 myProcessor,因为 @PostConstructinit() 方法没有特殊的上下文加载逻辑。

  1. public class Controller {
  2. @Value("${tt.f.processor.async}")
  3. private boolean isAsync;
  4. private MyProcessor myProcessor;
  5. public Controller(final AProcessorFactory factory) {
  6. this.myProcessor = factory.getInstance(isAsync);
  7. }
  8. }

你可以在测试的 @Before 步骤中指定这一点。

  1. @MockBean
  2. private AProcessorFactory factory;
  3. @Before
  4. public void setUp() {
  5. when(processor.process(any(Request.class), any(String.class)))
  6. .thenReturn(new TestResponse("123", SUCCESS, "", ""));
  7. when(factory.getInstance(any())).thenReturn(processor);
  8. }

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.

  1. public class Controller {
  2. @Value("${tt.f.processor.async}")
  3. private boolean isAsync;
  4. private MyProcessor myProcessor;
  5. public Controller(final AProcessorFactory factory) {
  6. this.myProcessor = factory.getInstance(isAsync);
  7. }
  8. }

You can specify this in a @Before step in your test.

  1. @MockBean
  2. private AProcessorFactory factory;
  3. @Before
  4. public void setUp() {
  5. when(processor.process(any(Request.class), any(String.class)))
  6. .thenReturn(new TestResponse("123", SUCCESS, "", ""));
  7. when(factory.getInstance(any())).thenReturn(processor)
  8. }

Spring will register your AProcessorFactory mock that has been loaded with the appropriate behaviors.

huangapple
  • 本文由 发表于 2020年9月2日 23:17:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/63708547.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定