Skip to content

Introducing the Ability to Mock Construction of Generic Types #2401

@brandon1024

Description

@brandon1024

First of all, thank you for building an awesome testing library!

I have recently started playing with mocked object construction. It's fantastic that this functionality is now available through plain ol' Mockito. It makes for some pretty elegant tests, especially when combined with @Mock using the MockitoExtension.

One limitation I've encountered is around mocking the constructions of parameterized types.

Here's what I'd like to accomplish:

@ExtendWith(MockitoExtension.class)
class DefaultKafkaConsumerTest {

    @Mock
    private MockedConstruction<KafkaConsumer<String, String>> kafkaConsumerMockedConstruction;

    @Test
    void testMyThing() {
        new DefaultKafkaConsumer<String, String>();
        final KafkaConsumer<String, String> mockConsumer = kafkaConsumerMockedConstruction.constructed().get(0);
        // ... assert
    }

Unfortunately, this doesn't seem to work, as indicated by this message:

Mockito cannot infer a static mock from a raw type for kafkaConsumerMockedConstruction

Instead of @Mock MockedConstruction you need to specify a parameterized type
For example, if you would like to mock Sample.class, specify

@Mock MockedConstruction<Sample>

as the type parameter. If the type is itself parameterized, it should be specified as raw type.

As suggested, I've updated my tests as follows:

@ExtendWith(MockitoExtension.class)
class DefaultKafkaConsumerTest {

    @Mock
    private MockedConstruction<KafkaConsumer> kafkaConsumerMockedConstruction;

    @Test
    void testMyThing() {
        new DefaultKafkaConsumer<String, String>();

        @SuppressWarnings("unchecked")
        final KafkaConsumer<String, String> mockConsumer = kafkaConsumerMockedConstruction.constructed().get(0);
        // ... assert
    }

I'm less fond of suppressing warnings everywhere. I've extracted the unchecked operation into a helper method, but I think that just covers up the problem.

I'm curious to understand the technical reason why the MockedConstruction generic parameter has to be a raw type. It's interesting that I can create generic mocks and argument captors, but I can't do this through mocked construction.

Thanks for your time!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions