【问题标题】:how to mock private variable in RestController class如何在 RestController 类中模拟私有变量
【发布时间】:2020-09-02 15:17:21
【问题描述】:

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

我正在使用工厂根据一些布尔标志来实例化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, "", ""));

}

【问题讨论】:

  • 重构您的类以使用构造函数注入将有助于提高代码的可测试性。 PostConstruct 会让 JUnit 很难意识到这种注入。
  • 在构造函数中将该标志设置为 swll
  • 我将如何在我的测试类中模拟/设置它。异步标志和 MyProcessor 实例
  • @shinjw - 使用 junit5 和构造函数注入,它会是什么样子?可以举个例子吗

标签: java spring junit mockito


【解决方案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 模拟。

【讨论】:

  • Junit5 会怎样? @BeforeAll 可以与 PostConstruct 一起使用吗?
  • 在之前的步骤中是合适的。
猜你喜欢
  • 1970-01-01
  • 2018-08-24
  • 2020-02-23
  • 1970-01-01
  • 1970-01-01
  • 2011-03-18
  • 1970-01-01
  • 1970-01-01
  • 2020-01-01
相关资源
最近更新 更多