mockito icon indicating copy to clipboard operation
mockito copied to clipboard

Seemingly random java.lang.AssertionError in MockUtil.getMockHandlerOrNull

Open mpiela opened this issue 1 year ago • 3 comments

Hi, we're experiencing an issue very similar to #2793 where some tests fail with an assertion error:

java.lang.AssertionError
	at org.mockito.internal.util.MockUtil.getMockHandlerOrNull(MockUtil.java:160)
        .....

The issue started occuring in some of our tests after upgrading to mockito 5.12.0 where "inline" became the default for the mock maker. In some tests similar to the attached example we have mocks that have to be created using SUBCLASS and to make these tests pass we have to swich all mocks to SUBCLASS. It seemed a bit "code-smelly" during code review so here I am...

I've spent some time trying to prepare a piece of code that would fail each time - see attached example mockito-issue.zip

It's a simple spring-mvc controller test, perform a mvn clean install to run it. What I've discovered so far:

  1. The test works every time when using java 17.0.10-jbr from sdkman
  2. The test fails every time when using 17.0.12-tem from sdkman

Then, while using the "failing" 17.0.12-tem java I noticed that making ANY of the following changes makes the tests pass:

  • Removing SomeControllerTest.tearDown method (which is empty!)
  • Removing any of the thirdDependency* bean definitions from SomeControllerTestContext (so reducing the number of mocks in the spring context from 16 to 15)
  • Switching the MockMaker from SUBCLASS to INLINE in SomeControllerTestContext.secondDependency

mpiela avatar Jul 30 '24 11:07 mpiela

I have the same issue with mockito 4.11.0 and java11 (temurin and coretto 11.0.18)

skhvostyuk avatar Sep 02 '24 11:09 skhvostyuk

I analyzed the Problem and tracked it down to

getMockHandlerOrNull

with the line

assert getMockMaker(handler.getMockSettings().getMockMaker()) == mockMaker;

Assuming we have more than one Mockmaker in the mockMakers field, this line will seriously fail, if the Mockmakers themselves do not ensure only returning handlers of the same type as themselves. SubclassByteBuddyMockMaker does return any Handler of a mock and thus this line will fail.

almondtools avatar Sep 26 '24 18:09 almondtools

I have similar issue as above, mockito 5.17, java11. assert getMockMaker(handler.getMockSettings().getMockMaker()) == mockMaker;

We are using both inline and subclass mocks. The issue in getMockHandlerOrNull happens when order of mockMakers is as follows: Image

Inline maker as second.

Image

Both handlers mockMakers are null:

Image

Image

However mockMaker variable is of class ByteBuddyMockMaker and the assertion is raised.

Image

When there is following order of mocks:

Image Inline mock first.

It works, but “by chance”.

Handlers are not null as before:

Image

But, again, for both handlers mockmaker are null:

Image

However in this scenario:

Image

is Inline and assertion passes because default mockmaker is Inline:

Image

The root cause is (probably) in Handler – whatever type of handler, its mockMaker is null leading to random failures (in current shape logic getMockHandlerOrNull works only ‘by chance’). Shouldn't mockMaker be set properly on handler when object is mocked or spied? @TimvdLippe could you have a look? You've fixes similar issue in https://github.com/mockito/mockito/issues/2823

tomaszbechey avatar Apr 29 '25 17:04 tomaszbechey

Had this issue, too, in Quarkus context, which uses inline MockMaker by default. I had some tests, which created mocks with SUBCLASS:

Mockito.withSettings().mockMaker(MockMakers.SUBCLASS)

It randomly failed the whole test suite with the AssertionError above. I've rewritten the tests, to not use SUBCLASS, and it seems to be gone.

sco0ter avatar Oct 14 '25 13:10 sco0ter