-
We have one Micronaut microservice that has a few thousand @MicronautTest cases in it. After upgrading to Micronaut 4 a small subset of the tests have become flaky, especially during CI, throwing the following error from the DefaultBeanContext related to a @MockBean dependency: I haven't seen any other issues logged against Micronaut with this error and we don't see it any of our other microservices (although no other services have more than 1000 test cases). The issue occurs pretty regularly in CI, which runs quicker because of a lack of corporate anti-virus software, but some developers have seen it occasionally appear on their development machines. The tests that fail are always from a subset of tests that involve mocking several @client dependencies using Mockito and @MockBean. It isn't really clear to me what "enabled" means in the context of the bean definition here. Any tips on what this code might be doing or how to debug this would be greatly appreciated. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
Can you provide a stacktrace? |
Beta Was this translation helpful? Give feedback.
-
Here is the stack trace, which shows it occurs when injecting a mock calculationEngineClient:
This is the relevant code that sets up mocks (@MicronautTest and other setup is inherited from base classes and annotations):
As mentioned, the issue occurs very sporadically when running locally, but quite reliably during CI runs (~90% of the time a few tests will fail). I've never been able to recreate the issue while debugging locally. Furthermore, I've never even seen the failure occur on my local machine however another developer did see it occasionally on their machine (~30% of the time). The 3,786 test cases take about 9 minutes to run on the developer's machine who was seeing the issue, about 18 minutes on my machine, and about 43 minutes in CI. |
Beta Was this translation helpful? Give feedback.
-
I had a theory that setting up the mocks was somehow taking "too long" (9 different when() clauses are setup for the two mocks), triggering a race condition, or somehow interfering with @MockBean, so I moved the setup logic to the test class's constructor and the issue no longer occurs. The constructor logic runs prior to Micronaut's JUnit extension which should make the @MockBean method resolve quicker. It is still not clear to me what is going on behind the scenes, but this completely resolved the issue with "The definition is not enabled". public abstract class ApiTestWithFormularyAndCalculationEngineMocks extends ApiTestWithDb {
protected FormularyClient formularyClient;
protected CalculationEngineClient calculationEngineClient;
public ApiTestWithFormularyAndCalculationEngineMocks() {
formularyClient = mock(FormularyClient.class);
setupFormularyClientDefaultMocks(formularyClient);
calculationEngineClient = mock(CalculationEngineClient.class);
setupCalculationEngineClientDefaultMocks(calculationEngineClient);
}
@MockBean(FormularyClient.class)
public FormularyClient getMockFormularyClient() {
return formularyClient;
}
@MockBean(CalculationEngineClient.class)
public CalculationEngineClient getMockCalculationEngineClient() {
return calculationEngineClient;
}
} |
Beta Was this translation helpful? Give feedback.
I had a theory that setting up the mocks was somehow taking "too long" (9 different when() clauses are setup for the two mocks), triggering a race condition, or somehow interfering with @MockBean, so I moved the setup logic to the test class's constructor and the issue no longer occurs. The constructor logic runs prior to Micronaut's JUnit extension which should make the @MockBean method resolve quicker. It is still not clear to me what is going on behind the scenes, but this completely resolved the issue with "The definition is not enabled".