Search code examples
javaspring-bootjunitmockito

How do I mock a REST template exchange?


I have a service in which I need to ask an outside server via rest for some information:

public class SomeService {

    public List<ObjectA> getListofObjectsA() {
        List<ObjectA> objectAList = new ArrayList<ObjectA>();
        ParameterizedTypeReference<List<ObjectA>> typeRef = new ParameterizedTypeReference<List<ObjectA>>() {};
        ResponseEntity<List<ObjectA>> responseEntity = restTemplate.exchange("/objects/get-objectA", HttpMethod.POST, new HttpEntity<>(ObjectAList), typeRef);
        return responseEntity.getBody();
    }
}

How can I write a JUnit test for getListofObjectsA()?

I have tried with the below:

@RunWith(MockitoJUnitRunner.class)
public class SomeServiceTest {
    private MockRestServiceServer mockServer;

    @Mock
    private RestTemplate restTemplate;

    @Inject
   private SomeService underTest;

@Before
public void setup() {
    mockServer = MockRestServiceServer.createServer(restTemplate);
    underTest = new SomeService(restTemplate);
    mockServer.expect(requestTo("/objects/get-objectA")).andExpect(method(HttpMethod.POST))
            .andRespond(withSuccess("{json list response}", MediaType.APPLICATION_JSON));
}

    @Test
    public void testGetObjectAList() {
    List<ObjectA> res = underTest.getListofObjectsA();
    Assert.assertEquals(myobjectA, res.get(0));
}

However the above code does not work, it shows that responseEntitty is null. How can I correct my test to properly mock restTemplate.exchange?


Solution

  • You don't need MockRestServiceServer object. The annotation is @InjectMocks not @Inject. Below is an example code that should work

    @RunWith(MockitoJUnitRunner.class)
    public class SomeServiceTest {
        @Mock
        private RestTemplate restTemplate;
    
        @InjectMocks
        private SomeService underTest;
    
        @Test
        public void testGetObjectAList() {
            ObjectA myobjectA = new ObjectA();
            //define the entity you want the exchange to return
            ResponseEntity<List<ObjectA>> myEntity = new ResponseEntity<List<ObjectA>>(HttpStatus.ACCEPTED);
            Mockito.when(restTemplate.exchange(
                Matchers.eq("/objects/get-objectA"),
                Matchers.eq(HttpMethod.POST),
                Matchers.<HttpEntity<List<ObjectA>>>any(),
                Matchers.<ParameterizedTypeReference<List<ObjectA>>>any())
            ).thenReturn(myEntity);
    
            List<ObjectA> res = underTest.getListofObjectsA();
            Assert.assertEquals(myobjectA, res.get(0));
        }