Why is mockito not injecting a mock of a generic type?

90 Views Asked by At

I'm performing a general upgrade of our codebase (Java 11 to 17, Spring upgrade, Hibernate upgrade, etc), as well as some test code, moving from Mockito 1.10 to 5.8.0, and found that some of our tests are no longer work as they used to.

I have tried a few different versions of Mockito in the 5.x range, as well as experimenting with going between @Mock and @MockBean for my mocked class. I've boiled down the issue to these unit tests that I have added to GenericTypeMockTest in the Mockito repo that I have pulled down locally:

    @Nested
    public class ClassWithGenericFieldsTest {
        public class UnderTestWithGenericField<T> {
            T toBeInjected;
        }
        public class ConcreteClass {}

        @Mock ConcreteClass injectedMock;

        @InjectMocks UnderTestWithGenericField<ConcreteClass> underTestWithGenericField = new UnderTestWithGenericField<ConcreteClass>();

        @Test
        void testWithGenericFields() {
            assertNotNull(injectedMock);
            // verify that we can match the type parameters of the class under test
            assertEquals(injectedMock, underTestWithGenericField.toBeInjected);
        }
    }
    @Nested
    public class SuperClassWithGenericFieldsTest {
        public class SuperWithGenericField<T> {
            List<T> listToBeInjected;
            T instanceToBeInjected;
        }
        public class ChildClass extends SuperWithGenericField<ConcreteClass> {}
        public class ConcreteClass {}

        @Mock List<ConcreteClass> injectedList;
        @Mock ConcreteClass injectedInstance;

        @InjectMocks ChildClass underTestWithGenericField = new ChildClass();

        @Test
        void testWithGenericFields() {
            assertNotNull(injectedList);
            assertNotNull(injectedInstance);
            // verify that we can match the type parameters of the class under test
            assertEquals(injectedList, underTestWithGenericField.listToBeInjected);
            assertEquals(injectedInstance, underTestWithGenericField.instanceToBeInjected);
        }
    }

In the first test, changing the field toBeInjected and mock injectedMock to List<T> fixes the test, but that's not reflective of the code I'm maintaining. As illustrated, neither works in the second version of the test.

1

There are 1 best solutions below

0
On

I also encountered the same issue when I did the spring boot migration. The issue is with the mockito version. You can refer to the github issue attached here. As a fix, you can downgrade the mockito core version to 5.1.1. Then it will work. https://github.com/mockito/mockito/issues/3019