gstackoverflow
gstackoverflow

Reputation: 37106

Why Cannot I use Mock and InjectMocks together?

valid construction:

@InjectMocks
SomeClass sc = mock(SomeClass.class);

Invalid construction:

@InjectMocks
@Mock
SomeClass sc;

I want to inject mocks to another mock. I want to use only annotation style.

Why was in Mockito forbid second construction ?

Update

example:

    public class ArrTest {
    private SomeClass someClass;

    public List<String> foo(){
        anotherMethod(); // I suppose that this method works. I want to test it separately.
        //logic which I need to test
        return someClass.doSmth();// I suppose that this method works. I want to test it separately.
    }
    public void anotherMethod(){
        ///...
    }
}

public class SomeClass {
    public List<String> doSmth(){
        return null;
    }
}

test:

public class ArrTestTest {
    @InjectMocks
    ArrTest arrTest = Mockito.mock(ArrTest.class);
    @Mock
    SomeClass someClass;
    @Test
    public void fooTest(){        
         Mockito.when(someClass.doSmth()).thenReturn(new ArrayList<String>());
         Mockito.doNothing().when(arrTest).anotherMethod();
         System.out.println(arrTest.foo());
    }

}

Upvotes: 4

Views: 5315

Answers (3)

Jeff Bowman
Jeff Bowman

Reputation: 95714

@InjectMocks specifically indicates that the annotated field will NOT contain a mock. Annotating @InjectMocks @Mock is not just unsupported—it's contradictory.

To return stubs wherever possible, use this:

@Mock(answer=Answers.RETURNS_DEEP_STUBS)
YourClass mockYourClassWithDeepStubs;

But heed the official documentation for this Answer:

WARNING: This feature should rarely be required for regular clean code! Leave it for legacy code. Mocking a mock to return a mock, to return a mock, (...), to return something meaningful hints at violation of Law of Demeter or mocking a value object (a well known anti-pattern).

Good quote I've seen one day on the web: every time a mock returns a mock a fairy dies.

Upvotes: 1

tones
tones

Reputation: 504

It sounds like you're trying to do something that doesn't really make sense. You shouldn't need to inject any dependencies into your mock since mocks by definition don't have any behaviour until you define it with when(mock.someMethod()).thenAnswer() or some variation.

(except perhaps if you're using a spy(), but you've specifically said you're using a @Mock).

Maybe you could explain your use case and why you're trying to inject dependencies into a mock?

Upvotes: 2

David
David

Reputation: 2702

A mock doesn't have any real implementation. @InjectMocks would try to find and call setters for whatever mock objects have already been created and pass them in. Mockito "knows" that this is kinda pointless on a mock, since there won't be any way to get the mock objects back out, much less do anything meaningful with them.

Upvotes: 0

Related Questions