question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

@InjectMocks ignores @Mock's name of generic type

See original GitHub issue

When injecting two fields of the same type with @InjectMocks, the @Mock’s name is not taken into account.

public class Foo {
    Bar<Integer> f1;
    Bar<Boolean> f2;

    public Foo(Bar<Integer> f1, Bar<Boolean> f2) {
        this.f1 = f1;
        this.f2 = f2;
    }
}
interface Bar<T> {
}
@RunWith(MockitoJUnitRunner.class)
public class FooTest {

    @Mock(name = "f1")
    Bar<Integer> f1;

    @Mock(name = "f2")
    Bar<Boolean> f2;

    @InjectMocks
    Foo foo;

    @Test
    public void test() {
        System.out.println(foo.f1);
        System.out.println(foo.f2);
    }
}

Expected result: f1 mock --> f1, and f2 mock --> f2. Actual result: f1 mock is getting injected into both fields.

Version: mockito-core:2.7.22

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:1
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

5reactions
ChristianSchwarzcommented, May 11, 2017

Indeed it would be nice if Mockito would support construtor injection by parameter name! Constructor injection is different beast that field injection. For field injection the name of the target field can be used to match to the mock of the same name. For parameters this is not always possible, it depends on how the code was compiled and on the java version that run the code:

Method Parameter Reflection (RFE: JDK-8004841): You can obtain the names of the formal parameters of any method or constructor with the method java.lang.reflect.Executable.getParameters. However, .class files do not store formal parameter names by default. To store formal parameter names in a particular .class file, and thus enable the Reflection API to retrieve formal parameter names, compile the source file with the -parameters option of the javac compiler.


Long story short: It is possibe to implement construtor injection via parameter names. But your tests may break if they are not compiled or run with the same setup.

This limitation should be documented. A workaround would be to name the mock “argN” to indicate the parameter index for injection, but this has many other downsides.

3reactions
ubhidecommented, Feb 18, 2020

Just to keep this bug alive, I am definitely having this issue in v1.10.19

My workaround was to not use InjectMocks and create the object manually in the setup. Kinda messy but it gets around this issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Mockito - Mock generic objects of the same type - Stack Overflow
I am trying to mock my GenericDao objects, using Mockito Framework 1.9. 5 and JUnit 4.11, but Mockito does always mock the first...
Read more >
Mockito: Why You Should Not Use InjectMocks Annotation to ...
Mockito will try to inject mocks only either by constructor injection, setter injection, or property injection in order and as described below.
Read more >
Mockito 2.6.8 API - javadoc.io
@ Captor simplifies creation of ArgumentCaptor - useful when the argument to capture is a nasty generic class and you want to avoid...
Read more >
Annotation Magic with Mockito: InjectMocks - Encora
Field injection; mocks will first be resolved by type (if a single type match injection will happen regardless of the name), then, if...
Read more >
Automatic instantiation of @Spies, @InjectMocks ... - CWIKI.US
//instead: @Spy BeerDrinker drinker = new BeerDrinker(); //you can write: @Spy BeerDrinker drinker; //same applies to @InjectMocks ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found