Проблема кодирования в тестах Spring Boot MockMvc

Я реализую интеграционные тесты для своего приложения Spring Boot, используя MockMvc. Проблема в том, что мне нужно использовать русские символы в телах запросов/ответов, и они продолжают превращаться в нечитаемые символы.

Вот моя конфигурация:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = InfoApplicationConfig.class)
@TestPropertySource(properties = {"spring.config.location=classpath:application-it.yml"})
@AutoConfigureMockMvc
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class TerminalControllerIT {

    @Autowired
    MockMvc mockMvc;

    @LocalServerPort
    private int port;

    private String baseUrl = "http://localhost";

    private final String validTerminalId = "eee00000-0000-0000-0000-000000000000";

    private final String invalidTerminalId = "abc00000-0000-0000-0000-000000123456";

    private NewTerminalDto testSubject;

    @Autowired
    private static ObjectMapper objectMapper;

    @Autowired
    private TerminalRepository terminalRepository;

    @BeforeEach
    public void setUp() {
        testSubject = NewTerminalDto.builder().country("Россия").region("Москва").city("Москва")
                .street("Ленина").buildingNumber("12A")
                .roomNumber("101").terminalCoordinate("55.7558,37.6176")
                .postCode("123456").terminalNumber("123")
                .isClosed(false).cashDepositWithdrawal(false).moneyTransfer(true).payment(true).nfc(true)
                .banknotesPerPack(100)
                .biometrics(false).encashmentService(true).cashDeposit(true)
                .openingTime("08:00")
                .closingTime("18:00")
                .build();
        baseUrl = baseUrl.concat(":" + port).concat("/api/v1/info-service/terminals");
    }

Тест 1:

@Test
    @DisplayName("Should return terminal by id")
    void getTerminalInfoByIdPositiveTest() throws Exception {
        MvcResult result = mockMvc.perform(get(baseUrl + "/" + validTerminalId)
                        .characterEncoding("UTF-8")
                        .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andReturn();

        String jsonResponse = result.getResponse().getContentAsString();
        TerminalGetResponse actualResponse = objectMapper.readValue(jsonResponse, TerminalGetResponse.class);

        assertNotNull(actualResponse);
        assertNotNull(actualResponse.getTerminalNumber());
        assertNotNull(actualResponse.getRegion());
        assertEquals("ТРМ-001", actualResponse.getTerminalNumber());
        assertEquals("Москва", actualResponse.getRegion());
    }

Ответ:

Expected :ТРМ-001
Actual   :ТРÐ-001

Тест 2:

 @Test
    @DisplayName("Adding branch")
    void addBranch() throws Exception {
        BranchPayload body = BranchStubs.createBranchPayload(0);

        mockMvc.perform(post(baseUrl)
                        .content(objectMapper.writeValueAsBytes(body))
                        .contentType(MediaType.APPLICATION_JSON_VALUE)
                        .characterEncoding("UTF-8"))
                .andExpect(status().isOk());

        BankBranchesModel bankBranchesModel = BankBranchesModel.builder().branchNumber(body.getBranchNumber()).build();

        assertNotNull(bankBranchesRepository.findOne(Example.of(bankBranchesModel)).orElse(null));
    }

Результат:

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /api/v1/info-service/branches
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=UTF-8", Content-Length:"907"]
             Body = {"branchNumber":"8500","country":"??????","region":"?????????? ???????","city":"????????","street":"???????????","buildingNumber":"5","postCode":"117997","branchCoordinate":"55.696225, 37.544539","ramp":true,"phoneNumber":"74955555550","isClosed":false,"openingTime":"00:00","closingTime":"23:55","dayOfWeek":["???????????","???????","?????","???????","???????"],"currencyExchange":true,"foreignCurrency":true,"moneyTransfer":true,"cashWithdrawal":true,"payment":true,"replenishCard":true,"replenishAccount":true,"hasDeposit":true,"hasCredit":true,"consultation":true,"insurance":true,"bik":"044525220","kpp":"773643002","inn":"7707083890","paymentAccount":"40702810562000000000","correspondentAccount":"30101810400000000225","bankNameFull":"?? «FinTech Bank»","okpo":"09610477","ogrn":"1027700057410","swift":"LIBBRUMM007"}
    Session Attrs = {}

...

MockHttpServletResponse:
           Status = 400
    Error message = null
          Headers = [Content-Type:"application/json"]
     Content type = application/json
             Body = {"bankNameFull":"must match \"^(?!\\s*$)[0-9A-Za-z?-??-? !\"#$%&'()*+,\\-./:;<=>?@\\[\\\\\\]^_{|}~]{1,30}$\""}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

Пытался установить кодировку в свойствах тестового класса/для objectMapper/дляockMvc – у меня ничего из этого не сработало. Также попробовал сделать это в своих файлах миграции, что на самом деле не имеет смысла, поскольку символы в запросе уже перепутаны.

Upd Забыл упомянуть, что приложение отлично работает при тестировании с помощью Swagger или Postman.

какая проверка у вас есть для поля «bankNameFull»? вы отправляете это значение «?? «FinTech Bank»» из того, чем вы поделились...

Carlos 25.06.2024 16:32

@Carlos, эти два знака вопроса на самом деле являются русскими буквами. Позже я обновлю пост заглушкой, которую использую для тестов.

D Bystrov 25.06.2024 16:39

Результат: Результат где?

g00se 25.06.2024 18:10

@g00se в окне инструмента «Выполнить» в IntelliJ

D Bystrov 25.06.2024 19:56

Верно. Как это String там печатается? "\u041C\u043E\u0441\u043A\u0432\u0430"

g00se 25.06.2024 20:41

@g00se, использующий escape-символы, также оказывается в вопросительных знаках. Даже при печати с помощью System.out.println

D Bystrov 26.06.2024 06:58

В этом случае это может указывать на отсутствие поддержки кириллицы в выходном шрифте. Попробуйте изменить

g00se 26.06.2024 10:01

Действительно ли ваш файл хранится в формате UTF8?

knittl 27.06.2024 11:36
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
8
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Перепробовав все возможные решения, я наткнулся на русские форумы, где моя проблема последовательно обсуждалась. Итак, изменение локали Windows по умолчанию на UTF-8 в конце концов сработало для меня. Вот краткое руководство: https://exploratory.io/note/exploratory/Enabling-UTF-8-on-Windows-hYc3yWL0

Другие вопросы по теме