I have a class which has 2 fields of similar types. I have mocked them both. But when I use InjectMocks, inject mocks wrongly injects a single mock into both those fields.
Here is the example code class:
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import java.util.Set;
import java.util.function.Consumer;
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class TestClass {
private final Consumer<Set<Integer>> intConsumer;
private final Consumer<Set<String>> stringConsumer;
void PrintClass(){
System.out.println("intConsumers: " + intConsumer);
System.out.println("stringConsumers: " + stringConsumer);
}
}
Here is the test class:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Set;
import java.util.function.Consumer;
@RunWith(MockitoJUnitRunner.class)
public class TestClassTest {
@Mock private Consumer<Set<Integer>> intConsumer;
@Mock private Consumer<Set<String>> stringConsumer;
@InjectMocks private TestClass testClass;
@Test
public void testPrint(){
testClass.PrintClass();
}
}
Here is the output when I run the test: testPrint() - intConsumer is injected into both intConsumer and stringConsumer.
intConsumers: intConsumer
stringConsumers: intConsumer
Process finished with exit code 0
I am using Maven.
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.7.19</version>
</dependency>
I created this private constructor especially for testing using InjectMocks. I do not want to make it public/package-private so I cannot use field injection. I also do not want to expose these fields using public setters. Also, I do not want to make my fields non-final.
I have tried upgrading the mockito-version to 3.5.10 but it still has this bug. I have also tried making my fields final and using setters - then Injection works fine - but I do not want to expose my setters. I have also tried naming mocks @Mock(name = "mock") with constructor injection but it does not work as well.
Am I missing something here? Is there a way to get it working with private constructor injection?