'How to automatically disable a Spring bean when running a unit test?
I have a service class which starts a thread and run some background tasks. These tasks should not be run while I'm running a unit test. The service class itself is so simple that it doesn't need to be unit tested. It is like:
@Service
public class BackgroundTaskService {
@PostConstruct
public void startTask() {
// ...
}
}
Currently I'm setting a system property to declare that a unit test is running:
@RunWith(SpringRunner.class)
@SpringBootTest
public class SomeTest {
static {
System.setProperty("unit_testing", "true");
}
@Test
public void test() {}
}
Then I can check:
@PostConstruct
public void startTask() {
if (System.getProperty("unit_testing") != null) {
return; // skip background tasks
}
}
I'd like to know if there is a better way to do that.
Solution 1:[1]
A prettier way to handle this would be
@Service
public class BackgroundTaskService {
@PostConstruct
@Profile("!test")
public void startTask() {
// ...
}
}
or even
@PostConstruct
public void startTask() {
if(env.acceptsProfiles("!test")) { // env is @Autowired Environment
// start task
}
}
Only if the test profile is not active, the @PostConstruct method is run. In a Spring environment you want to use the tools Spring gives you, so use a profile instead of some custom indicator.
Solution 2:[2]
It's not a good practice to skip unit tests for even simple code, but if you really want to do that you can have a look at this thread. Instead of a property you can have a static boolean variable.
Note to community: I'm new to this forum so my reputation doesn't allow me to comment. Thanks.
Solution 3:[3]
Consider @MockBean. The presence of a @MockBean will remove the bean that is being mocked:
Any existing single bean of the same type defined in the context will be replaced by the mock.
Instead of invoking the original behavior, all the methods of the mock will just return a blank or empty value by default:
By default, for all methods that return a value, a mock will return either null, a primitive/primitive wrapper value, or an empty collection, as appropriate.
https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html
This may or may not be good enough for one's use case, to replace the normal bean with a dummy bean rather than disable the bean completely.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | Alexander Taylor |
