13

I'm writing unit tests using Mockito and I'm having problems mocking the injected classes. The problem is that two of the injected classes are the same type, and only differentiated by their @Qualifier annotation. If I tried to simply mock SomeClass.class, that mock is not injected and that object is null in my tests. How can I mock these objects?

public class ProfileDAL {

    @Inject
    @Qualifier("qualifierA")
    private SomeClass someClassA ;

    @Inject
    @Qualifier("qualifierB")
    private SomeClass someClassB ;

    //...various code, not important
}

@RunWith(MockitoJUnitRunner.class)
public class ProfileDALLOMImplTest {

    @InjectMocks
    private ProfileDALLOMImpl profileDALLOMImpl = new ProfileDALLOMImpl();

    @Mock
    private SomeClass someClassA;
    @Mock
    private SomeClass someClassB;

    private SomeResult mockSomeResult = mock(SomeResult.class);

    @Test
    public void testSomeMethod() {
        when(someClassA .getSomething(any(SomeArgment.class)).thenReturn(mockSomeResult);
        Int result = profileDALLOMImpl.someTest(This isn't relevant);
    }

 }
ntalbs
  • 28,700
  • 8
  • 66
  • 83
tamuren
  • 1,072
  • 4
  • 15
  • 32
  • How does your test code look like ? I always explicitly call `Mockito.mock(SomeClass.class)` to create my mocks, keeping out of my unit tests any magic provided by annotations. You should be able to do the same, if you inject your dependencies via constructor or setters. Is there a good reason it's not the case ? – rcomblen Mar 18 '13 at 19:41
  • Could you possibly demonstrate injecting these dependencies without the use of @InjectMocks? I updated my Q to demonstrate how my test is set up. – tamuren Mar 18 '13 at 20:04
  • When all hope fails, you can always use powermock to inject private fields. There is a clear guide behind the following link: https://stackoverflow.com/questions/36173947/mockito-mock-private-field-initialization –  Jun 09 '19 at 11:12

3 Answers3

11

I have tried mocking two objects with the same type with Mockito 1.9.5 using JUnit and it works.

See: http://static.javadoc.io/org.mockito/mockito-core/1.9.5/org/mockito/InjectMocks.html

Relevant type info from the doc:

"Field injection; mocks will first be resolved by type, then, if there is several property of the same type, by the match of the field name and the mock name."

And this one which seems to say you should make the mock name match the field name for all your mocks when you have two of the same type:

"Note 1: If you have fields with the same type (or same erasure), it's better to name all @Mock annotated fields with the matching fields, otherwise Mockito might get confused and injection won't happen."

Perhaps this latter one is biting you?

Eel Lee
  • 3,513
  • 2
  • 31
  • 49
splonk
  • 1,045
  • 6
  • 11
3

Just confirmed what Splonk pointed out and it works that way in Mockito 1.9.5, as soon as I removed one of the mocked classes, it failed.

So, in your case, make sure you have both of the mocked classes with the same name as in the class in your test:

@Mock
private SomeClass someClassA;
@Mock
private SomeClass someClassB;
hesparza
  • 131
  • 5
0

If you don't use annotation, you get something like

public class MyClass {
    private MyDependency myDependency;

    public void setMyDependency(MyDependency myDependency){
        this.myDependency = myDependency;
    }
}

and

import org.junit.Before;
import org.junit.Test;

import static org.mockito.Mockito.*;

public class MyTest {

    private MyClass myClass;
    private MyDependency myDependency;

    @Before
    public void setUp(){
        myClass = new MyClass();
        myDependency = mock(MyDependency.class);
        myClass.setMyDependency(myDependency);
    }

    @Test
    public void test(){
        // Given

        // When

        // Then
    }
}

You can do just the same if your object has its dependencies specified via constructor rather than via setter. I guess your dependency injection framework can annotate the setters the same way you annotate private fields, but now your tests don't rely on any dependency injection framework.

rcomblen
  • 4,579
  • 1
  • 27
  • 32