Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito + Spring + @PostConstruct, mock initialization error, why is @PostConstruct called?

Tags:

I have a set up like:

Bean class:

private final Map<String, String> configCache = new HashMap<>();
@PostConstruct
private void fillCache() {  (...) configCache.clear();} 

TestConfig class:

@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
@Primary
public Bean beanMock() {
    return Mockito.mock(Bean.class);
}

Test class: which @Autowires the bean.

It seems when Mockito is creating the mock in TestConfig, it calls @PostConstruct which in turn seems to be called before the map field is initialized so it throws an exception.

My question is:

  • Why does Mockito call @PostConstruct?
  • How can I disable @PostConstruct for mocking?

EDIT: Apparently the call is done after the instantiation just before Spring retrns the bean from a Config's @Bean method

like image 559
Whimusical Avatar asked Feb 08 '17 12:02

Whimusical


People also ask

When @PostConstruct is called in Java?

Methods marked with the @PostConstruct will be invoked after the bean has been created, dependencies have been injected, all managed properties are set, and before the bean is actually set into scope.

When @PostConstruct is invoked?

The PostConstruct annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization. This method MUST be invoked before the class is put into service. This annotation MUST be supported on all classes that support dependency injection.

What does @PostConstruct do in spring?

When we annotate a method in Spring Bean with @PostConstruct annotation, it gets executed after the spring bean is initialized. We can have only one method annotated with @PostConstruct annotation. This annotation is part of Common Annotations API and it's part of JDK module javax.

What can I use instead of PostConstruct?

We can replace @PostConstruct with BeanFactoryPostProcessor and PriorityOrdered interface. The first one defines an action that ought to be executed after the object's instantiation. The second interface tells the Spring the order of the component's initialization.


1 Answers

Mockito isn't calling @PostConstruct -- Spring is. You say that in your test you use @Autowired, which is not a Mockito annotation.

If you meant to use @Mock, you'll find that Mockito won't call your @PostConstruct method.

In other words, write your test class like this:

@Mock Bean myBean;

@Before
public void before() {
    MockitoAnnotations.initMocks();
}
like image 156
john16384 Avatar answered Sep 23 '22 11:09

john16384