Skip to content

Commit

Permalink
Additional document
Browse files Browse the repository at this point in the history
  • Loading branch information
s.tikhomirov committed Aug 7, 2022
1 parent 6ad5270 commit 5a2f02e
Show file tree
Hide file tree
Showing 10 changed files with 702 additions and 526 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,5 @@ First public BETA-versions are coming soon
[Issues to be fixed/Requred features](https://github.com/Tinkoff/neptune/issues)

[Change list](https://github.com/Tinkoff/neptune/releases)

Site: [https://tinkoff.github.io/neptune/site/](https://tinkoff.github.io/neptune/site/)
2 changes: 1 addition & 1 deletion site.documentation/source/quick_start/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

- Maven или gradle

- ⚠️ Необходим доступ к maven-репозиторию [https://nexus-new.tcsbank.ru/repository/mvn-bigops-qa](https://nexus-new.tcsbank.ru/repository/mvn-bigops-qa)_.
- ⚠️ _Необходим доступ к maven-репозиторию [https://nexus-new.tcsbank.ru/repository/mvn-bigops-qa](https://nexus-new.tcsbank.ru/repository/mvn-bigops-qa)_.
Если доступа нет, то рекомендуется необходимые модули собрать локально. См [документ для контрибъюторов](start_to_contribute.md)

- Указать в зависимостях необходимые модули. Описание каждого модуля см. соответствующей секции документации.
Expand Down
33 changes: 18 additions & 15 deletions site.documentation/source/spring/mock.mvc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

[API](https://tinkoff.github.io/neptune/spring.mock.mvc/index.html)

## Почему _Neptune_ ?
## Сравнение _Neptune + MockMVC_ с другими вариантами

Ниже небольшое сравнение того как выглядит один и тот же тест:

Expand All @@ -24,6 +24,7 @@
### Тест с использованием Mock MVC, без реализации шагов

```java

@SpringBootTest
@AutoConfigureMockMvc
public class SomeTest {
Expand Down Expand Up @@ -65,9 +66,9 @@ public class SomeTest {
var someCalculatedValue = //вычисление чего-то с использованием
//responseDto

assertThat("Some calculated value",
someCalculatedValue.getSomethingElse(),
is(someExpeсtedValue2));
assertThat("Some calculated value",
someCalculatedValue.getSomethingElse(),
is(someExpeсtedValue2));

//и т.д.
}
Expand All @@ -80,6 +81,7 @@ public class SomeTest {
какие действия выполняются и каков их результат. Тогда

```java

@SpringBootTest
@AutoConfigureMockMvc
public class SomeTest {
Expand Down Expand Up @@ -152,7 +154,7 @@ public class SomeTest {

var someCalculatedValue = //вычисление чего-то с использованием
//responseDto
assertSomeCalculatedValue(someCalculatedValue, someExpectedValue2);
assertSomeCalculatedValue(someCalculatedValue, someExpectedValue2);
//и т.д.
}
}
Expand All @@ -161,10 +163,11 @@ public class SomeTest {
### Тест с использованием Mock MVC и Neptune

```java

@SpringBootTest
@AutoConfigureMockMvc
public class SomeTest {

@Autowired
private ObjectMapper objectMapper;

Expand All @@ -182,18 +185,18 @@ public class SomeTest {
// будут проверены все ожидания
.expectStatus(200) //проваленные будут выделены в отчете
.expectJsonPathValue("$.successOrder", 5)
//предусмотрен механизм десериализации
//предусмотрен механизм десериализации
.thenGetBody(SomeResponseDto.class)
);

check("Response body",
responseDto,
match("Some field value",
SomeResponseDto::getSomething,
is(someExpectedValue)),
match("Some calculated value",
dto -> {/*вычисление чего-то с использованием*/},
is(someExpeсtedValue2)));
check("Response body",
responseDto,
match("Some field value",
SomeResponseDto::getSomething,
is(someExpectedValue)),
match("Some calculated value",
dto -> {/*вычисление чего-то с использованием*/},
is(someExpeсtedValue2)));
}
}
```
Expand Down
2 changes: 1 addition & 1 deletion site.documentation/source/spring/mock.mvc/response.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Request / Response
# MockMVC. Request / Response

```java
import org.springframework.boot.test.context.SpringBootTest;
Expand Down
209 changes: 208 additions & 1 deletion site.documentation/source/spring/web.test.client/index.md
Original file line number Diff line number Diff line change
@@ -1 +1,208 @@
# Web Test Client
# Web Test Client

Данный модуль:

- является дополнением к
стандартному [Spring WebTestClient](https://spring.getdocs.org/en-US/spring-framework-docs/docs/testing/integration-testing/webtestclient.html)
- данный модуль предоставляет фасад , который фиксирует работу _Spring WebTestClient_ в виде шагов
- данный модуль исправляет потенциальные неудобства флоу _Spring WebTestClient_

```{eval-rst}
.. include:: webtestclient_dependencies.rst
```

[API](https://tinkoff.github.io/neptune/spring.web.testclient/index.html)

## ## Сравнение _Neptune + WebTestClient_ с другими вариантами

Ниже небольшое сравнение того как выглядит один и тот же тест:

- с использованием WebTestClient, без реализации шагов
- с использованием WebTestClient и с реализацией шагов
- с использованием WebTestClient и Neptune

### Тест с использованием WebTestClient, без реализации шагов

```java

@SpringBootTest
@AutoConfigureWebTestClient
public class SomeTest {

@Autowired
private WebTestClient client;

@Test
public void semeAPITest() {
SomeResponseDto responseDto = client.post()
.uri("/something")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(Mono.just(new SomeDTO()), SomeDTO.class)
.exchange()
//Если текущее ожидание не выполнилось,
//на нем тест остановится и последующие ожидания не будут
//проверены. Хотелось бы видеть более полную картину несоответствий
//до того, как начать багофикс
.expectStatus().isOk()
//хотелось бы частые ожидания иметь
//в более доступном и коротком виде
.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectBody(SomeResponseDto.class)
.returnResult()
.getResponseBody();

//дельнейшие вычисления
//проверка поля ответа
assertThat("Some field value",
responseDto.getSomething(),
is(someExpectedValue));

var someCalculatedValue = //вычисление чего-то с использованием
//responseDto

assertThat("Some calculated value",
someCalculatedValue.getSomethingElse(),
is(someExpeсtedValue2));

//и т.д.
}
}
```

### Тест с использованием WebTestClient и с реализацией шагов

Предположим, что результат интеграционного теста должен быть оформлен в отчет, описывающий по шагам,
какие действия выполняются и каков их результат. Тогда

```java

@SpringBootTest
@AutoConfigureWebTestClient
public class SomeTest {

@Autowired
private ObjectMapper objectMapper;

@Autowired
private WebTestClient client;

@Step("Подготовить тело запроса")
private SomeDTO prepareRequestBody() {
var toReturn = new SomeDTO();
addAttachment("Request body", "application/json",
objectMapper.writeValueAsString(toReturn));
return toReturn;
}

@Step("Получаем ответ на запрос POST /something")
private ResponseSpec getResponsePostSpec(SomeDTO body) {
var postExchangeSpec = client.post()
.uri("/something")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(Mono.just(new SomeDTO()), SomeDTO.class)
.exchange();

//делаем аттачи, фиксируем параметры и т.д.
return postExchangeSpec;
}

@Step("Выполняем проверку ответа и возвращаем прочитанное тело")
private SomeResponseDto getSomeResponseDto(
ResponseSpec responseSpec) {

SomeResponseDto bodyContent = responseSpec.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectBody(SomeResponseDto.class)
.returnResult()
.getResponseBody();

addAttachment("Response body", "application/json",
objectMapper.writeValueAsString(bodyContent));
return bodyContent;
}

@Step("Проверить тело ответа")
private void assertSomeDTO(SomeResponseDto toCheck, Object expected) {
assertThat("Some field value",
responseDto.getSomething(),
is(expected));
}

@Step("Проверить полученное у тела значение")
private void assertSomeCalculatedValue(SomeCalculatedValue toCheck, Object expected) {
assertThat("Some calculated value",
someCalculatedValue.getSomethingElse(),
is(expected));
}


@Test
public void semeAPITest() {
//Тест стал короче, НО!!!!
//У нас появился толстый слой шагов, который надо организовывать
//и поддерживать.
//Может начаться дублирование кода, если аналогичные действия
//встречаются в других тестах.
//Организация библиотеки шагов сделает тест непрозрачным,
//в перспективе затруднит модификацию/рефактринг тестов

var body = prepareRequestBody();
var response = getResponsePostSpec(body);
var dto = getSomeResponseDto(response);
assertSomeDTO(dto, someExpectedValue);

var someCalculatedValue = //вычисление чего-то с использованием
//responseDto
assertSomeCalculatedValue(someCalculatedValue, someExpectedValue2);
//и т.д.
}
}
```

### Тест с использованием WebTestClient и Neptune

```java

@SpringBootTest
@AutoConfigureWebTestClient
public class SomeTest {

//Поле ниже можно не объявлять
//@Autowired
//private WebTestClient client;

@Test //все описанное в тесте сформирует шаги разной вложенности
//и автоматически сформирует аттачи
public void semeAPITest() {
SomeResponseDto responseDto = webTestClient(
send(webClient -> webClient.post()
.uri("/something")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(Mono.just(new SomeDTO()), SomeDTO.class),
Dto.class)
// будут проверены все ожидания
.expectStatus(200) //проваленные будут выделены в отчете
.expectContentType(APPLICATION_JSON)
.thenGetBody()
);

check("Response body",
responseDto,
match("Some field value",
SomeResponseDto::getSomething,
is(someExpectedValue)),
match("Some calculated value",
dto -> {/*вычисление чего-то с использованием*/},
is(someExpeсtedValue2)));
}
}
```

```{toctree}
:hidden:
response.md
```
Loading

0 comments on commit 5a2f02e

Please sign in to comment.