WebTestClient. Request / Response#

import static ru.tinkoff.qa.neptune.spring
    .web.testclient.SendRequestAction.send;
import static ru.tinkoff.qa.neptune.spring.web.testclient
    .WebTestClientContext.webTestClient;

@SpringBootTest
@AutoConfigureWebTestClient
public class MyTest {

    @Test(description = "Простая отправка запроса")
    public void myTest() {
        webTestClient(
            //описывается запрос:
            // метод (GET, POST, PUT или Delete)
            send(webClient -> webClient.post()
            .uri("/something")
            .contentType(MediaType.APPLICATION_JSON) //и
            //параметры
            .accept(MediaType.APPLICATION_JSON)
            .body(Mono.just(new SomeDTO()), SomeDTO.class),
            //Опциональный параметр, который можно не указывать.
            //От его наличия зависит, как будут сформированы 
            //ожидания к контенту ответа, как к dto, или 
            //как к тексту/массиву байтов
            Dto.class)
        );
    }
}

Ниже пример с явным использованием объекта org.springframework.test.web.reactive.server.WebTestClient

import org.springframework.test.web.reactive.server.WebTestClient;

import static ru.tinkoff.qa.neptune.spring
    .web.testclient.SendRequestAction.send;
import static ru.tinkoff.qa.neptune.spring.web.testclient
    .WebTestClientContext.webTestClient;

@SpringBootTest
@AutoConfigureWebTestClient
public class MyTest {

    @Autowired //Или любой другой вариант
    private WebTestClient client; //инициализации поля или переменной

    @Test(description = "Простая отправка запроса")
    public void myTest() {
        webTestClient(
            send(client, //явная передача объекта WebTestClient
            webClient -> webClient.post()
            .uri("/something")
            .contentType(MediaType.APPLICATION_JSON) //и
            .accept(MediaType.APPLICATION_JSON)
            .body(Mono.just(new SomeDTO()), SomeDTO.class),
            Dto.class)
        );
    }
}

WebTestClient. Описание ожиданий#

Методы, с помощью которых можно описать ожидаемый ответ, можно найти:

Ниже простой пример

import static ru.tinkoff.qa.neptune.spring
    .web.testclient.SendRequestAction.send;
import static ru.tinkoff.qa.neptune.spring.web.testclient
    .WebTestClientContext.webTestClient;

@SpringBootTest
@AutoConfigureWebTestClient
public class MyTest {

    @Test(description = "Пример описания ожидаемого ответа")
    public void myTest() {
        webTestClient(
            send(webClient -> webClient.post()
            .uri("/something")
            .contentType(MediaType.APPLICATION_JSON) //и
            .accept(MediaType.APPLICATION_JSON)
            .body(Mono.just(new SomeDTO()), SomeDTO.class))
            // Часто используемые ожидания имеют  
            .expectStatus(200) //упрощенную запись
            .expectContentType(APPLICATION_JSON)
            /////////////////////////////////////////
            //
            //Так же, при необходимости, есть возможности описывать
            //ожидания в функциональном стиле
            .expectStatus(statusAssertions -> {
            //некое вычисление или алгоритм
            return statusAssertions.isOk();
            })
            .expectContent(headerAssertions -> {
            //некое вычисление или алгоритм
            return headerAssertions.contentType(APPLICATION_JSON);
            })
        );
    }
}

Пример описания ожидания к телу ответа, которое прочитано как текст/массив байтов

import static ru.tinkoff.qa.neptune.spring
    .web.testclient.SendRequestAction.send;
import static ru.tinkoff.qa.neptune.spring.web.testclient
    .WebTestClientContext.webTestClient;

@SpringBootTest
@AutoConfigureWebTestClient
public class MyTest {

    @Test(description = "Пример описания ожидаемого ответа, " +
            "чье тело прочитано как текст/массив байтов")
    public void myTest() {
        webTestClient(
            send(webClient -> webClient.post()
            .uri("/something")
            .contentType(MediaType.APPLICATION_JSON) //и
            .accept(MediaType.APPLICATION_JSON)
            .body(Mono.just(new SomeDTO()), SomeDTO.class))
            //можно описывать ожидания к json/xml тексту
            //или к массиву байтов    
            .expectBodyJsonPathEquals("some.path", 1)
        );
    }
}

Пример описания ожидания к телу ответа, которое прочитано как DTO

import static org.hamcrest.Matchers.*;

import static ru.tinkoff.qa.neptune.spring
    .web.testclient.SendRequestAction.send;
import static ru.tinkoff.qa.neptune.spring.web.testclient
    .WebTestClientContext.webTestClient;

@SpringBootTest
@AutoConfigureWebTestClient
public class MyTest {

    @Test(description = "Пример описания ожидаемого ответа, " +
            "чье тело прочитано как DTO")
    public void myTest() {
        webTestClient(
            send(webClient -> webClient.post()
            .uri("/something")
            .contentType(MediaType.APPLICATION_JSON) //и
            .accept(MediaType.APPLICATION_JSON)
            .body(Mono.just(new SomeDTO()), SomeDTO.class), Dto.class)
            //ожидание для всего тела     
            .expectBody(equalTo(new Dto()))
            //описание того, ЧТО проверяется    
            .expectBody("Some field value",
            //описываем, как получить проверяемое значение
            Dto::someField,
            equalTo(someValue))
        );
    }
}

WebTestClient. Тело ответа#

Важно:

Прочитанное как текст / массив байтов#

import static ru.tinkoff.qa.neptune.spring
    .web.testclient.SendRequestAction.send;
import static ru.tinkoff.qa.neptune.spring
    .web.testclient.WebTestClientContext.webTestClient;

@SpringBootTest
@AutoConfigureWebTestClient
public class MyTest { //когда не указано, в какие объекты должна 
//происходить десериализация тела ответа

    @Test
    public void myTest() {
        //по умолчанию тело ответа представляется как массив байтов
        byte[] body = webTestClient(send(/*параметры запроса*/)
            //ожидания
            .thenGetBody()
        );

        //так же можно вернуть тело ответа в виде строки
        String body2 = webTestClient(send(/*параметры запроса*/)
            //ожидания
            .thenGetBodyAsString()
        );
    }
}

Прочитанное как DTO#

import static ru.tinkoff.qa.neptune.spring
    .web.testclient.SendRequestAction.send;
import static ru.tinkoff.qa.neptune.spring
    .web.testclient.WebTestClientContext.webTestClient;

@SpringBootTest
@AutoConfigureWebTestClient
public class MyTest {

    @Test
    public void myTest() {
        Dto body = webTestClient(send(/*параметры запроса*/,
            //так же можно использовать
            //org.springframework.core.ParameterizedTypeReference
            Dto.class)
            //ожидания
            .thenGetBody());

        Object value = webTestClient(send(/*параметры запроса*/,
            Dto.class)
            //ожидания
            //
            // описание объекта, который следует получить    
            .thenGetValue("Value of the field 'getSomeValue'",
            //описание получаемого результата в виде функции
            Dto::getSomeValue)
            // можно указать один или несколько критериев,  
            // которым должен соответствовать получаемый объект.
            // Так же доступны criteriaOr(criteria...), 
            // criteriaOnlyOne(criteria...)
            // criteriaNot(criteria...)    
            .criteria("Описание критерия, " +
            "которому должен соответствовать " +
            "получаемый объект", dto -> {
            /*предикат, как работает критерий*/
            })
            //можно указать, что должно быть выброшено исключение,  
            // если получаемый объект пустой / null / не соответствует
            // перечисленным критериям    
            .throwOnNoResult()
        );
    }
}

List#

import java.util.List;

import static ru.tinkoff.qa.neptune.spring
    .web.testclient.SendRequestAction.send;
import static ru.tinkoff.qa.neptune.spring
    .web.testclient.WebTestClientContext.webTestClient;

@SpringBootTest
@AutoConfigureWebTestClient
public class MyTest {

    @Test
    public void myTest() {

        List<Object> value = webTestClient(send(/*параметры запроса*/,
            //так же можно использовать
            //org.springframework.core.ParameterizedTypeReference
            Dto.class)
            //ожидания
            //
            //описание листа, который следует получить
            .thenGetList("Value of the field 'listValue'",
            //описание получения списка в виде функции
            Dto::listValue)
            //дополнительные уточняющие параметры    
        );
    }
}
Уточняющие параметры шага, который возвращает лист. Шаг не предусматривает время на ожидание
//Можно указать один или несколько критериев,
//которым должен соответствовать
//каждый элемент результирующего листа.
// Так же доступны criteriaOr(criteria...),
// criteriaOnlyOne(criteria...)
// criteriaNot(criteria...)
.criteria("Описание критерия, которому должен соответствовать " +
    "каждый элемент, который попадет в результирующий лист", item -> {
    /*предикат, как работает критерий*/
})
//-------------------------------------------
//Можно указать, что должно быть выброшено исключение,
// если непустой лист не удалось получить (не было ни одного элемента,
//который бы соответствовал перечисленным критериям,
// или непустой лист просто не был получен)
.throwOnNoResult()
//ТАКЖЕ ЕСТЬ СЛЕДУЮЩИЕ ОПЦИИ:
//-------------------------------------------
//1. можно указать сколько объектов,
//которые соответствуют критериям,
//нужно вернуть
.returnListOfSize(3)
//-------------------------------------------
//2. можно указать, до элемента с каким индексом
//нужно собрать результирующие элементы,
//индекс - индекс объекта в наборе элементов,
//которые соответствуют критериям
.returnBeforeIndex(7)
//.returnAfterIndex(8) либо после какого элемента
//----------------------------------------------
//3. Либо можно перечислить индексы элементов,
// которые следует вернуть.
//Индексы - индексы объектов в наборе элементов,
//которые соответствуют критериям
.returnItemsOfIndexes(0, 3, 5)
//-------------------------------------------
//4. можно указать, при достижении какого количества
//ВСЕХ объектов, которые соответствуют критериям,
//должен быть возвращен результат
.returnIfEntireSize(isEqual(8))
//-------------------------------------------
//5. можно указать, при достижении каких условий,
//которым должен соответствовать лист ВСЕХ объектов,
//соответствующих критериям,
//можно возвращать результирующий лист/суб-лист
.returnOnCondition("Описание условия", list -> {
    /*предикат, как работает критерий*/
})
//так же доступны returnOnConditionOr(criteria...),
// returnOnConditionOnlyOne(criteria...)
// returnOnConditionNot(criteria...)
//------------------------------------------
//Если не нашлось столько подходящих объектов, чтобы вернуть результат,
//или весь суб-лист подходящих по критериям элементов,
// который должен вернуться как результат,
// не соответствует каким-то критериям -
// будет выброшено исключение с подробным описанием

Массив#

import java.util.List;

import static ru.tinkoff.qa.neptune.spring
    .web.testclient.SendRequestAction.send;
import static ru.tinkoff.qa.neptune.spring
    .web.testclient.WebTestClientContext.webTestClient;

@SpringBootTest
@AutoConfigureWebTestClient
public class MyTest {

    @Test
    public void myTest() {

        List<Object> value = webTestClient(send(/*параметры запроса*/,
            //так же можно использовать
            //org.springframework.core.ParameterizedTypeReference
            Dto.class)
            //ожидания
            //
            //описание листа, который следует получить
            .thenGetArray("Value of the field 'arrayValue'",
            //описание получения списка в виде функции
            Dto::arrayValue)
            //дополнительные уточняющие параметры            
        );
    }
}
Уточняющие параметры шага, который возвращает массив. Шаг не предусматривает время на ожидание
//Можно указать один или несколько критериев,
//которым должен соответствовать
//каждый элемент результирующего массива.
// Так же доступны criteriaOr(criteria...),
// criteriaOnlyOne(criteria...)
// criteriaNot(criteria...)
.criteria("Описание критерия, которому должен соответствовать " +
    "каждый элемент, который попадет в результирующий массив", item -> {
    /*предикат, как работает критерий*/
})
//------------------------------------------
//Можно указать, что должно быть выброшено исключение,
// если непустой массив не удалось получить (не было ни одного элемента,
//который бы соответствовал перечисленным критериям,
// или непустой массив просто не был получен)
.throwOnNoResult()
//ТАКЖЕ ЕСТЬ СЛЕДУЮЩИЕ ОПЦИИ:
//------------------------------------------
//1. можно указать сколько объектов,
//которые соответствуют критериям,
//нужно вернуть
.returnArrayOfLength(3)
//-------------------------------------------
//2. можно указать, до элемента с каким индексом
//нужно собрать результирующие элементы,
//индекс - индекс объекта в наборе элементов,
//которые соответствуют критериям
.returnBeforeIndex(7)
//.returnAfterIndex(8) либо после какого элемента
//----------------------------------------------
//3. Либо можно перечислить индексы элементов,
// которые следует вернуть.
//Индексы - индексы объектов в наборе элементов,
//которые соответствуют критериям
.returnItemsOfIndexes(0, 3, 5)
//-----------------------------------------------
//4. можно указать, при достижении какого количества
//ВСЕХ объектов, которые соответствуют критериям,
//должен быть возвращен результат
.returnIfEntireLength(isEqual(8))
//------------------------------------------
//5. можно указать, при достижении каких условий,
//которым должен соответствовать массив ВСЕХ объектов,
//соответствующих критериям,
//можно возвращать результирующий массив/суб-массив
.returnOnCondition("Описание условия", array -> {
    /*предикат, как работает критерий*/
})
//так же доступны returnOnConditionOr(criteria...),
// returnOnConditionOnlyOne(criteria...)
// returnOnConditionNot(criteria...)
//------------------------------------------
//Если не нашлось столько подходящих объектов, чтобы вернуть результат,
//или весь суб-массив подходящих по критериям элементов,
// который должен вернуться как результат,
// не соответствует каким-то критериям -
// будет выброшено исключение с подробным описанием

Элемент Iterable#

import static ru.tinkoff.qa.neptune.spring
    .web.testclient.SendRequestAction.send;
import static ru.tinkoff.qa.neptune.spring
    .web.testclient.WebTestClientContext.webTestClient;

@SpringBootTest
@AutoConfigureWebTestClient
public class MyTest {

    @Test
    public void myTest() {

        Object value = webTestClient(send(/*параметры запроса*/,
            //так же можно использовать
            //org.springframework.core.ParameterizedTypeReference
            Dto.class)
            //ожидания
            //
            //описание объекта, который следует получить
            .thenGetValueFromIterable("A value from " +
            "the field 'listValue'",
            //описание получения списка в виде функции
            Dto::listValue)
            //дополнительные уточняющие параметры     
        );
    }
}
Уточняющие параметры шага, который возвращает элемент Iterable. Шаг не предусматривает время на ожидание
//Можно указать один или несколько критериев,
//которым должен соответствовать
//результирующий элемент из набора.
// Так же доступны criteriaOr(criteria...),
// criteriaOnlyOne(criteria...)
// criteriaNot(criteria...)
.criteria("Описание критерия, которому должен соответствовать " +
    "результирующий элемент из набора", item -> {
    /*предикат, как работает критерий*/
})
//------------------------------------------
//Можно указать, что должно быть выброшено исключение,
// если не был получен результирующий элемент (не было ни одного элемента,
//который бы соответствовал перечисленным критериям,
// или непустой набор просто не был получен)
.throwOnNoResult()
//ТАКЖЕ ЕСТЬ СЛЕДУЮЩИЕ ОПЦИИ:
//------------------------------------------
//1. Можно указать индекс элемента, который следует вернуть.
//Индекс - индекс объекта в наборе элементов,
//которые соответствуют критериям
.returnItemOfIndex(1)
//-----------------------------------------------
//2. можно указать, при достижении какого количества
//ВСЕХ объектов, которые соответствуют критериям,
//должен быть возвращен результат
.returnIfEntireSize(isEqual(8))
//------------------------------------------
//3. можно указать, при достижении каких условий,
//которым должен соответствовать набор ВСЕХ объектов,
//соответствующих критериям,
//можно возвращать результирующий элемент
.returnOnCondition("Описание условия", iterable -> {
    /*предикат, как работает критерий*/
})
//так же доступны returnOnConditionOr(criteria...),
// returnOnConditionOnlyOne(criteria...)
// returnOnConditionNot(criteria...)
//------------------------------------------
//Если не нашлось столько подходящих объектов, чтобы вернуть результат,
//или весь набор подходящих по критериям элементов,
// из которого должен быть взят результат,
// не соответствует каким-то критериям -
// будет выброшено исключение с подробным описанием

Элемент массива#

import static ru.tinkoff.qa.neptune.spring
    .web.testclient.SendRequestAction.send;
import static ru.tinkoff.qa.neptune.spring
    .web.testclient.WebTestClientContext.webTestClient;

@SpringBootTest
@AutoConfigureWebTestClient
public class MyTest {

    @Test
    public void myTest() {

        Object value = webTestClient(send(/*параметры запроса*/,
            //так же можно использовать
            //org.springframework.core.ParameterizedTypeReference
            Dto.class)
            //ожидания
            //
            //описание объекта, который следует получить
            .thenGetValueFromArray("A value from  " +
            "the field 'arrayValue'",
            //описание получения списка в виде функции
            Dto::arrayValue)
            //дополнительные уточняющие параметры     
        );
    }
}
Уточняющие параметры шага, который возвращает элемент массива. Шаг не предусматривает время на ожидание
//Можно указать один или несколько критериев,
//которым должен соответствовать
//результирующий элемент из массива.
// Так же доступны criteriaOr(criteria...),
// criteriaOnlyOne(criteria...)
// criteriaNot(criteria...)
.criteria("Описание критерия, которому должен соответствовать " +
    "результирующий элемент из массива", item -> {
    /*предикат, как работает критерий*/
})
//-----------------------------------------------
//Можно указать, что должно быть выброшено исключение,
// если не был получен результирующий элемент (не было ни одного элемента,
// который бы соответствовал перечисленным критериям,
// или непустой массив просто не был получен)
.throwOnNoResult()
//ТАКЖЕ ЕСТЬ СЛЕДУЮЩИЕ ОПЦИИ:
//-----------------------------------------------
//1. Можно указать индекс элемента, который следует вернуть.
//Индекс - индекс объекта в наборе элементов,
//которые соответствуют критериям
.returnItemOfIndex(1)
//-----------------------------------------------
//2. можно указать, при достижении какого количества
//ВСЕХ объектов, которые соответствуют критериям,
//должен быть возвращен результат
.returnIfEntireLength(isEqual(8))
//-----------------------------------------------
//3. можно указать, при достижении каких условий,
//которым должен соответствовать набор ВСЕХ объектов,
//соответствующих критериям,
//можно возвращать результирующий элемент
.returnOnCondition("Описание условия", array -> {
    /*предикат, как работает критерий*/
})
//так же доступны returnOnConditionOr(criteria...),
// returnOnConditionOnlyOne(criteria...)
// returnOnConditionNot(criteria...)
//------------------------------------------
//Если не нашлось столько подходящих объектов, чтобы вернуть результат,
//или весь суб-массив подходящих по критериям элементов,
// из которого должен быть взят результат,
// не соответствует каким-то критериям -
// будет выброшено исключение с подробным описанием