Reputation: 10300
I have a service class that uses a prototype scoped bean declared in the following way:
@Bean
@Scope(scopeName = SCOPE_PROTOTYPE, proxyMode = TARGET_CLASS)
MyBean myBean() {...}
And I have an integration test which looks like this:
@SpringBootTest
@ExtendWith(SpringExtension.class)
class MyServiceTest {
@Autowired
MyBean myBean;
// tests follow here
}
Problem: I need exactly the same instance of MyBean
in the test but Spring injects a different instance because the scope of the bean is 'prototype'.
Question: How to inject the same instance of a prototype scoped bean into a test?
Note: I cannot change the scope declaration of the bean.
Upvotes: 1
Views: 1580
Reputation: 14772
If you cannot change anything and you insist on injecting the bean straight off then it is impossible.
The documentation clearly states:
The non-singleton prototype scope of bean deployment results in the creation of a new bean instance every time a request for that specific bean is made. That is, the bean is injected into another bean or you request it through a getBean() method call on the container. As a rule, you should use the prototype scope for all stateful beans and the singleton scope for stateless beans.
You are injecting it into another bean.
Upvotes: 0
Reputation: 131396
You have two approaches.
Override MyBean
to make it a singleton bean :
@TestConfiguration
public class OverrideBeanConfigurationForTest {
@Bean
@Scope(scopeName = SCOPE_SINGLETON)
MyBean myBean() {...}
}
Or override it to return always the same bean :
@TestConfiguration
public class OverrideBeanConfigurationForTest {
MyBean myBean;
@Bean
@Scope(scopeName = SCOPE_PROTOTYPE, proxyMode = TARGET_CLASS)
MyBean myBean() {
if (myBean == null){
myBean = new MyBean(...),
}
return myBean;
}
}
Now import this configuration in your spring boot test and also specify the property spring.main.allow-bean-definition-overriding=true
as that is false
by default :
@SpringBootTest({"spring.main.allow-bean-definition-overriding=true"})
@ExtendWith(SpringExtension.class)
@Import(OverrideBeanConfigurationForTest.class)
class MyServiceTest {
@Autowired
MyBean myBean;
// tests follow here
}
Tested and works.
Upvotes: 2