1. Introduction

In this post, we will be testing REST APIs using SpringBootTest environment. We will also test independent services without loading the Spring Application Context. We will also see how to fix execution order in test methods.

You will learn

  • Mocking spring context environment for tests.
  • Inject mock object instances to test independent services without creating a spring environment for tests.
  • Organize test methods execution by names in ascending order.
  • Testing REST APIs with SpringRunner.
  • Testing independent services with MockitoJUnitRunner.

2. Dependency

Let’s add the test dependency required to run the test cases.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

3. REST APIs

We need a controller and a service class to create test cases. We are using ItemController and ItemManager classes from here.

4. Testing Rest APIs

Let’s create a tester class for testing ItemController.

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class ItemControllerTests {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private ObjectMapper objectMapper;
}

Let’s discuss the annotations used in ItemControllerTests.

  • @RunWith(SpringRunner.class)SpringRunner provides support for loading application context.
  • @SpringBootTestSpringBootTest annotation is used to find the spring boot application and use that to load application context.
  • @AutoConfigureMockMvcAutoConfigureMockMvc annotation is used to enable and auto-configure MockMvc for the test class.

It’s time to create tester methods. Let’s create methods to test the REST APIs.

....
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ItemControllerTests {

    ....

    @Test
    public void aSaveItems() throws Exception {
        ....
    }

    @Test
    public void bFetchItems() throws Exception {
        ....
    }

    @Test
    public void cFetchItem() throws Exception {
        ....
    }

    @Test
    public void dDeleteItems() throws Exception {
        ....
    }

    ....
}

We have created test methods to test all Rest controller mappings. Because we need some records to be stored before fetch or delete operation we need to apply execution order of test methods. To control the execution order of methods we are using FixMethodOrder with NAME_ASCENDING property.

4.1. Testing Post Mappings

Let’s create a RequestBuilder for sending Post requests to the Rest controller.

@Test
public void aSaveItems() throws Exception {

    ....

    for (Item item : items) {
        RequestBuilder requestBuilder = MockMvcRequestBuilders.post("/saveItem").accept(MediaType.APPLICATION_JSON)
            .content(objectMapper.writeValueAsBytes(item)).contentType(MediaType.APPLICATION_JSON);

        MvcResult result = mockMvc.perform(requestBuilder).andReturn();

        MockHttpServletResponse response = result.getResponse();

        assertEquals(HttpStatus.OK.value(), response.getStatus());

        Item responseItem = objectMapper.readValue(response.getContentAsByteArray(), Item.class);

        assertEquals(responseItem.toString(), item.toString());
    }
}

4.2. Testing Get Mappings

@Test
public void bFetchItems() throws Exception {
    RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/getItems").accept(MediaType.APPLICATION_JSON);

    MvcResult result = mockMvc.perform(requestBuilder).andReturn();

    String expected = objectMapper.writeValueAsString(items);

    JSONAssert.assertEquals(expected, result.getResponse().getContentAsString(), false);
}

4.3. Testing Delete Mappings

@Test
public void dDeleteItems() throws Exception {
    RequestBuilder requestBuilder = MockMvcRequestBuilders.delete(String.format("/deleteItem/%d", item.getCode()))
    .accept(MediaType.APPLICATION_JSON);

    MvcResult result = mockMvc.perform(requestBuilder).andReturn();

    MockHttpServletResponse response = result.getResponse();

    assertEquals(HttpStatus.OK.value(), response.getStatus());
}

5. Testing Independent Services

Testing independent services don’t require a spring complete environment to load. Let’s create a service tester class to test ItemManager service.

@RunWith(MockitoJUnitRunner.class)
public class ItemManagerTests {

    @InjectMocks
    private ItemManager itemManager;

    @InjectMocks
    ObjectMapper objectMapper;
}

Let’s discuss the annotations used in ItemManagerTests.

  • @RunWith(MockitoJUnitRunner.class)MockitoJUnitRunner provides support for Mockito mock and spies.
  • @InjectMocksInjectMocks annotation loads mock object instances.

Let’s create tests cases to test the service methods.

public class ItemManagerTests {

    ....

    @Test
    public void testItemsAPIs() throws Exception {
        for (Item mockItem : mockItems) {
            this.saveItem(mockItem);
        }
        this.fetchItems();
        for (Item mockItem : mockItems) {
            this.deleteItem(mockItem);
        }
    }

    public void fetchItems() throws Exception {
        List<Item> items = itemManager.getItems();

        String expected = objectMapper.writeValueAsString(mockItems);

        JSONAssert.assertEquals(expected, objectMapper.writeValueAsString(items), false);
    }

    private void saveItem(Item mockItem) throws Exception {

        itemManager.addItem(mockItem.getCode(), mockItem.getName());

        Item item = itemManager.getItem(mockItem.getCode());

        assertNotNull(item);
    }

    private void deleteItem(Item mockItem) throws Exception {

        itemManager.deleteItem(mockItem.getCode());

        Item item = itemManager.getItem(mockItem.getCode());

        assertNull(item);

    }
}

6. Running the tests

Now it’s time to execute the test cases.

Using Linux console go to project location and execute the command (mvn test). You will see the following screen after all the tests are done.

7. Conclusion

In this post, we have learned how to test REST APIs using SpringRunner and MockitoToJUnitRunner environments. We also learned how to fix execution order in test methods.

The complete source can be found over on GitHub.

Testing REST APIs using SpringRunner MockitoJUnitRunner
Tagged on:                     

Satish Pandey

I am an expert Java Spring Angular developer with 10+ years of rich and varied experience in developing end-to-end Web Applications. I maintain this blog and publish articles in my free time to help the community. Email: satish@cloudtechpro.com