Sunday, February 23, 2020

Spring Mockito and injection


I had a UnitTest to create.
I wanted to check a bean class , with some logical code.

This bean class had an internal Autowired internal bean, that I didn't care of , didn't want to check .

So how to setup a test around the original class without having to setup the internal Autowired class ...


The @InjectMocks means that this is the main class that we want to test, where we inject into it, if possible , the other Mock.
The @Mock  means that we want to wrap the class and to control it from outside , without taking care of its internal code.

Important:
do not forget the call
        MockitoAnnotations.initMocks(this);
which activate the injection



Here is the example code :


mport org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.List;

import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;

public class ConsumerPrivateMessageConversationMessageDataConverterTest {


    @InjectMocks    ConversationMessageDataConverter conversationMessageDataConverter = new ConversationMessageDataConverter();


    @Mock    UserACItemRetriever userACItemRetriever;

    @BeforeClass    public void setMockOutput() throws AccountConfigClientException {
        MockitoAnnotations.initMocks(this);
        when(userACItemRetriever.getItem(anyString(), anyLong())).thenReturn(null);
    }

    @Test    public void checkPrivateMessageFiltering() {
        conversationMessageDataConverter.convertToConversationHistoryMessageData(conversationDTO);

    }
}




The ConversationMessageDataConverter class uses  inside its code the UserACItemRetriever class 

@Componentpublic class ConversationMessageDataConverter {

    @Autowired    private UserACItemRetriever userACItemRetriever;


    public void convertToConversationHistoryMessageData( .... )  {
    }

}

Adjustement: 
17 Jan 2021 : I just paid attention that there's a difference between 
@Mock and @MockBean 
If you want your instance to be wrapped as a Mock but also considered 
and injected as a bean, the, you should use:
@MockBean

Here for more info 
https://stackoverflow.com/questions/42641853/spring-boot-integration-testing-with-mocked-services-components

No comments: