Create a new controller and hello service
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping("/hello") public String helloWorld(){ return "Hello World"; } }
JUnit 4 Code
@RunWith(SpringRunner.class)
@WebMvcTest(HelloWorldController.class)
JUnit 5 Code
@WebMvcTest(HelloWorldController.class)
Testing Simple Hello Controller
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.RequestBuilder; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import static org.junit.jupiter.api.Assertions.*; @WebMvcTest(HelloController.class) class HelloControllerTest { @Autowired private MockMvc mockMvc; @Test void helloWorld() throws Exception { // request GET /hello and application/json RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/hello") .accept(MediaType.APPLICATION_JSON); MvcResult result=mockMvc.perform(requestBuilder).andReturn(); //verify controller assertEquals("Hello World",result.getResponse().getContentAsString()); } }
Controller with status and content
@Test void helloWorldWithContentAndStatus() throws Exception { // request GET /hello and application/json RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/hello") .accept(MediaType.APPLICATION_JSON); MvcResult result=mockMvc.perform(requestBuilder) .andExpect(status().isOk()) .andExpect(MockMvcResultMatchers.content().string("Hello World")) .andReturn(); }
Controller with JSON Response
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.RequestBuilder; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(ObjectController.class) class ObjectControllerTest { @Autowired private MockMvc mockMvc; @Test void objReturnTest() throws Exception { RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/get-item") .accept(MediaType.APPLICATION_JSON); MvcResult result=mockMvc.perform(requestBuilder) .andExpect(status().isOk()) .andExpect(MockMvcResultMatchers.content().json("{\"id\":1,\"name\":\"Ball\"}")) .andReturn(); } }
JSON Assert
// JSON response should be exact may have space. @Test void jsonAssertionStrictTrueExceptSpaces() throws Exception { String actualJson = "{\"id\":1,\"name\":\"Ball\"}"; String expectedJson = "{\"id\":1,\"name\":\"Ball\"}"; JSONAssert.assertEquals(expectedJson, actualJson,true); } // JSON response should contain may have space. @Test void jsonAssertionStrictFalseExceptSpaces() throws Exception { String actualJson = "{\"id\":1,\"name\":\"Ball\",\"age\":33}"; String expectedJson = "{\"id\":1,\"name\":\"Ball\"}"; JSONAssert.assertEquals(expectedJson, actualJson,false); } // JSON response can be written without escape character if value does not contain spaces @Test void jsonAssertionWithoutEscapeCharacter() throws Exception { String actualJson = "{id:1,name:Ball,age:33}"; String expectedJson = "{id:1,name:Ball}"; JSONAssert.assertEquals(expectedJson, actualJson,false); }
Testing Controller invoking Business Layer
@MockBean BusinessService businessService; @Test void objReturnFromBusiness() throws Exception { when(businessService.getData()).thenReturn(new Item(1,"Ball")); RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/get-business-item") .accept(MediaType.APPLICATION_JSON); MvcResult result = mockMvc.perform(requestBuilder) .andExpect(status().isOk()) .andExpect(MockMvcResultMatchers.content().json("{id:1,name:Ball}")) .andReturn(); }
With the latest versions of Spring Boot (2.3+), the H2 database name is randomly generated each time you restart the server.
You can find the database name and URL from the console log.
RECOMMENDED:
Make the database URL a constant by configuring this in application.properties
.
spring.datasource.url=jdbc:h2:mem:testdb spring.data.jpa.repositories.bootstrap-mode=default
Business Layer Test
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.when; import java.util.Arrays; import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import com.in28minutes.unittesting.unittesting.data.ItemRepository; import com.in28minutes.unittesting.unittesting.model.Item; @ExtendWith(MockitoExtension.class) public class ItemBusinessServiceTest { @InjectMocks private ItemBusinessService business; @Mock private ItemRepository repository; @Test public void retrieveAllItems_basic() { when(repository.findAll()).thenReturn(Arrays.asList(new Item(2,"Item2",10,10), new Item(3,"Item3",20,20))); List<Item> items = business.retrieveAllItems(); assertEquals(100, items.get(0).getValue()); assertEquals(400, items.get(1).getValue()); } }
Repository Test
JUnit 4 Code
@RunWith(SpringRunner.class)
@DataJpaTest
JUnit 5 Code
@DataJpaTest
import org.json.JSONException; import org.junit.jupiter.api.Test; import org.skyscreamer.jsonassert.JSONAssert; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) public class ItemControllerIT { @Autowired private TestRestTemplate restTemplate; @Test public void contextLoads() throws JSONException { String response = this.restTemplate.getForObject("/all-items-from-database", String.class); JSONAssert.assertEquals("[{id:10001},{id:10002},{id:10003}]", response, false); } }
Integration Test
JUnit 4 Code
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
JUnit 5 Code
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
import org.json.JSONException; import org.junit.jupiter.api.Test; import org.skyscreamer.jsonassert.JSONAssert; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) public class ItemControllerIT { @Autowired private TestRestTemplate restTemplate; @Test public void contextLoads() throws JSONException { String response = this.restTemplate.getForObject("/all-items-from-database", String.class); JSONAssert.assertEquals("[{id:10001},{id:10002},{id:10003}]", response, false); } }
Use Specific Application properties for TestCases
import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest @TestPropertySource(locations= {"classpath:test-configuration.properties"}) //High priority and override any other config public class UnitTestingApplicationTests { @Test public void contextLoads() { } }
else create test>resources>application.properties
Hamcrest Matchers Tests
import org.junit.jupiter.api.Test; import java.util.Arrays; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; import static org.hamcrest.collection.IsCollectionWithSize.hasSize; class ItemRepositoryTest { @Test void hamcrestTest() { List<Integer> no = Arrays.asList(1, 2, 3, 4); assertThat(no, hasSize(4)); assertThat(no, hasItems(1, 2)); assertThat(no, everyItem(greaterThan(0))); assertThat(no, everyItem(lessThan(100))); assertThat("", isEmptyString()); assertThat("ABCDE", containsString("AB")); assertThat("ABCDE", startsWith("AB")); assertThat("ABCDE", endsWith("DE")); } }
AssertJ Tests
import static org.assertj.core.api.Assertions.assertThat; import java.util.Arrays; import java.util.List; import org.junit.jupiter.api.Test; public class AssertJTest { @Test public void learning() { List<Integer> numbers = Arrays.asList(12,15,45); //assertThat(numbers, hasSize(3)); assertThat(numbers).hasSize(3) .contains(12,15) .allMatch(x -> x > 10) .allMatch(x -> x < 100) .noneMatch(x -> x < 0); assertThat("").isEmpty(); assertThat("ABCDE").contains("BCD") .startsWith("ABC") .endsWith("CDE"); } }
JSONPathTest
import static org.assertj.core.api.Assertions.assertThat; import java.util.List; import org.junit.jupiter.api.Test; import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; public class JsonPathTest { @Test public void learning() { String responseFromService = "[" + "{\"id\":10000, \"name\":\"Pencil\", \"quantity\":5}," + "{\"id\":10001, \"name\":\"Pen\", \"quantity\":15}," + "{\"id\":10002, \"name\":\"Eraser\", \"quantity\":10}" + "]"; DocumentContext context = JsonPath.parse(responseFromService); int length = context.read("$.length()"); assertThat(length).isEqualTo(3); List<Integer> ids = context.read("$..id"); assertThat(ids).containsExactly(10000,10001,10002); System.out.println(context.read("$.[1]").toString()); System.out.println(context.read("$.[0:2]").toString()); System.out.println(context.read("$.[?(@.name=='Eraser')]").toString()); System.out.println(context.read("$.[?(@.quantity==5)]").toString()); } }
What are good TestCases
- The test should be readable
- The test should be fast.
- The test should be Isolated – fails only when issue with code.
- The test should be run often.
Website for Reference: http://xunitpatterns.com/
I’ve been surfing online more than three hours today, yet I never found any interesting article like yours.
It is pretty worth enough for me. Personally, if all site owners and bloggers made good content as you
did, the internet will be much more useful than ever before.
lasuna online order – buy himcolin purchase himcolin pill
purchase besivance online – besivance without prescription purchase sildamax without prescription
buy neurontin for sale – buy azulfidine without a prescription order azulfidine 500mg generic
Your blog is a true hidden gem on the internet. Your thoughtful analysis and in-depth commentary set you apart from the crowd. Keep up the excellent work!
order probenecid online – buy etodolac pills buy carbamazepine online cheap
oral celecoxib 200mg – cost celebrex 100mg indocin uk
order colospa 135mg sale – arcoxia cost order cilostazol 100 mg online cheap
voltaren tablet – aspirin sale order aspirin online
Your writing has a way of resonating with me on a deep level. It’s clear that you put a lot of thought and effort into each piece, and it certainly doesn’t go unnoticed.
purchase rumalaya without prescription – shallaki generic endep pills
mestinon 60 mg tablet – imuran 50mg ca purchase azathioprine without prescription