Testing RestWeb - DmitryGontarenko/usefultricks GitHub Wiki

RestTemplate

RestTemplate - это клиент, с помощью которого можно делать простые HTTP запросы.
Для совершения таких запросов RestTemplate имеет несколько методов.

Рассмотрим несколько из них на примере.
Контроллер:

@RestController
public class Controller {

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String getHello() {
        return "Hello!";
    }


}

Метод getForObject - позволяет получить новый объект указанного типа.

        String forObject = restTemplate.getForObject("http://localhost:8085/hello", String.class);
        assertThat(forObject, is("Hello!"));

Метод exchange - представляет собой более гибкую версию предыдущего метода. Может принимать в качестве параметров HTTP-метод, заголовки и тело в качетсве входных параметров. Возвращает ResponseEntity.

        ResponseEntity<String> responseEntity = restTemplate.exchange(
                "http://localhost:8085/hello",
                HttpMethod.GET,
                HttpEntity.EMPTY,
                String.class
        );
        assertThat(responseEntity.getStatusCode(), is(HttpStatus.OK));
        assertThat(responseEntity.getBody(), notNullValue());

Рассмотрим еще один пример.
Контроллер:

@RestController
public class Controller {

    private List<String> carList = new ArrayList<String>() {{
       add("Mazda");
       add("BMW");
    }};

    @RequestMapping(method = RequestMethod.GET)
    public List<String> getAll() {
        return carList;
    }
    
    @RequestMapping(method = RequestMethod.POST)
    public List<String> saveCar(@RequestBody String car) {
        System.out.println(car);
        carList.add(car);

        return carList;
    }
}

Получаем и сохраняем данные с помощью exchange:

        // GET
        ResponseEntity<List<String>> getAll = restTemplate.exchange(
                "http://localhost:8085",
                HttpMethod.GET,
                HttpEntity.EMPTY,
                new ParameterizedTypeReference<List<String>>() {}
        );
        assertThat(getAll.getStatusCode(), is(HttpStatus.OK));
        assertThat(getAll.getBody(), notNullValue());

        // POST
        ResponseEntity<List<String>> postFerrari = restTemplate.exchange(
                "http://localhost:8085",
                HttpMethod.POST,
                new HttpEntity<>("Ferrari"),
                new ParameterizedTypeReference<List<String>>() {
                }
        );
        List<String> body = postFerrari.getBody();
        assertThat(postFerrari.getStatusCode(), is(HttpStatus.OK));
        assertThat(body, notNullValue());
        assertThat(body.get(body.size() - 1), is("Ferrari"));

WireMock

WireMock - эмулятор HTTP запросов. Он позволяет создавать и тестировать различные API.

Подключение зависимости:

<dependency>
 <groupId>com.github.tomakehurst</groupId>
 <artifactId>wiremock</artifactId>
 <version>2.23.2</version>
 <scope>compile</scope>
</dependency>

Создадим начальную конфигурацию:

class MockApplicationTests {
	private static final int PORT = 8089;
	private static final String HOST = "localhost";

	private RestTemplate restTemplate;
	private static WireMockServer server = new WireMockServer(PORT);

	@BeforeEach
	void setUp() {
		server.start();
		configureFor(HOST, PORT);

		restTemplate = new RestTemplate();
	}

	@AfterEach
	void tearDown() {
		server.shutdownServer();
	}

        // ...
}

Теперь приступим к созданию методов с использованием заглушек.
Создадим заглушку для GET-метода, которая возвращает заданную строку со статусом 200 OK.

	@Test
	public void getTest() {
		String mockResponse = "MockResponse";
		
		stubFor(get(urlEqualTo("/test"))
				.willReturn(aResponse()
						.withStatus(HttpStatus.OK.value())
						.withBody(mockResponse)));

		String forObject = restTemplate.getForObject("http://localhost:8089/test", String.class);
		assertThat(forObject, is(mockResponse));
	}

Создадим заглушку для POST-метода, которая возвращает заданный JSON, статус и заголовок:

@Test
	public void postTest() {
		Map<String, Object> userJson = new HashMap<>();
		userJson.put("username", "admin");
		userJson.put("password", randomAlphabetic(10));

		String responseBody;
		try {
			responseBody = new ObjectMapper().writeValueAsString(userJson);
		} catch (JsonProcessingException e) {
			throw new RuntimeException(e);
		}

		stubFor(post(urlEqualTo("/save"))
				.willReturn(aResponse()
						.withStatus(HttpStatus.CREATED.value())
						.withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
						.withBody(responseBody)));

		ResponseEntity<String> exchange = restTemplate.exchange(
				"http://localhost:8089/save",
				HttpMethod.POST,
				HttpEntity.EMPTY,
				String.class
		);
		assertThat(exchange.getStatusCode(), is(HttpStatus.CREATED));
		assertThat(exchange.getBody(), is(responseBody));
	}
⚠️ **GitHub.com Fallback** ⚠️