在 @PostConstruct 之后调用 Mockito @Before 方法

Posted

技术标签:

【中文标题】在 @PostConstruct 之后调用 Mockito @Before 方法【英文标题】:Mockito @Before method is called after @PostConstruct 【发布时间】:2019-07-01 09:59:32 【问题描述】:

这是我的简化代码:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MockitoSpringBootTest 

    @MockBean
    private MyBean myBean;


    @Before
    private void before()
        Mockito.when(myBean.getSomeString()).thenReturn("TEST"));
    



@Service
private class TestClass 

    @Autowired
    private MyBean myBean;

    @PostConstruct
    public void initialize() 
        myBean.getSomeString(); //SmartNull - method is not stubbed yet
    


我的问题是我需要存根MyBean 方法,然后任何其他具有此对象自动装配的类将运行@BeforeClass 方法。现在@Before 方法在任何自动装配这个bean 的类的@PostConstruct 之后执行(不止一个)。

MyBean 作为模拟自动装配,但方法没有存根,所以我得到:“SmartNull 由这个未存根的方法调用模拟返回:”

有没有办法在 Spring 容器初始化中设置模拟 bean 的优先级?

【问题讨论】:

这是无效的语法。您不能注释初始化程序块。 @Before()private MyBean myBean 后面少了一个分号。 ("TEST")) 行的末尾有一个额外的括号。请在发布之前运行您的代码。 @PostConstruct方法被调用时,myBean已经被自动绑定了,还是还是null呢? @isnot2bad 是的 - 它作为模拟自动装配,但方法尚未存根,因此返回智能 null 是否调用了 initMocks()? 符合预期。在执行测试方法之前初始化应用程序上下文,因此它将构造所有 bean。 @Before 在测试方法被执行并且上下文已经被初始化之前被调用。像这样使用@MockBean 时,您无法更改此设置。您可以创建一个专门的配置并手动模拟 bean 并直接注册您想要的行为,这是唯一的解决方法。 【参考方案1】:

使用@TestConfiguration 而不是@MockBean 可能有助于解决这个问题。

@TestConfiguration
    static class Configuration 
        @Bean
        public BeanToMock name() 
            // return mock object           
        
    

并用@ContextConfiguration注释测试类:

@ContextConfiguration(classes = TestClassName.Configuration.class)

【讨论】:

【参考方案2】:

也许不是最优雅的解决方法,但您可以在静态块中模拟行为。静态块中的代码在@Before@PostConstruct 之前执行。我不认为,使用注释 (@MockBean) 进行模拟会起作用,但它也可以通过编程方式完成。

【讨论】:

以上是关于在 @PostConstruct 之后调用 Mockito @Before 方法的主要内容,如果未能解决你的问题,请参考以下文章

@PostConstruct注解小结

为啥使用@PostConstruct?

@PostConstruct方法的使用以及原理,@Component+@PostConstruct方法将一个方法完成初始化操作

周记2020.3.2~2020.3.8

@PostConstruct 和 @PreDestroy 指定初始化和销毁方法

Spring @value @Scope @PostConstruct @predestory