I have an integration test which worked well using...
# general
d
I have an integration test which worked well using Spring Boot 2.7.12. When upgrading to Spring Boot 3.x all the tests respond with a 500 INTERNAL_SERVER_ERROR instead of the expected 200 or 401, …
Copy code
<!--    <wiremock.version>2.27.2</wiremock.version>-->
    <wiremock.version>3.0.0-beta-10</wiremock.version>
The test class:
Copy code
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl;
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson;
import static <http://com.github.tomakehurst.wiremock.client.WireMock.post|com.github.tomakehurst.wiremock.client.WireMock.post>;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.assertj.core.api.Assertions.assertThat;

import com.xxx.malcolm.api.ProxyRequestDto;

import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.http.Fault;
import java.util.Collections;
import java.util.Map;
import lombok.Data;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
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;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

@DirtiesContext
@ExtendWith({
    SpringExtension.class,
    OauthMockTestExtension.class,
    SalesforceMockTestExtension.class
})
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@ContextConfiguration(initializers = {OauthMockTestExtension.class, SalesforceMockTestExtension.class}, classes = MalcolmApplication.class)
public class MalcolmIT {

    @LocalServerPort
    private int port;

    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private WireMockServer oauthServer;

    @Autowired
    private WireMockServer salesforce;

    @BeforeEach
    void setUp() {
        oauthServer.resetAll();
        salesforce.resetAll();
    }

    private String getHost() {
        return String.format("<http://localhost>:%d", port);
    }

    private HttpEntity<ProxyRequestDto> createHttpEntity(String brand, String country, String resource, HttpMethod method,
        Map<String, Object> body) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("X-Brand", brand);
        headers.add("X-Country", country);

        return new HttpEntity<>(new ProxyRequestDto(resource, method, body), headers);
    }

    @Test
    @DisplayName("Request with missing properties for OAuth username and password should return a HTTP 401")
    void withNoConfiguredUsernameAndPassword() {
        oauthServer.stubFor(post(anyUrl())
            .willReturn(aResponse()
                .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .withStatus(HttpStatus.UNAUTHORIZED.value())
                .withBodyFile("oauth/failure.json")
            ));

        ResponseEntity<Object> response = restTemplate.exchange(
            getHost(),
            <http://HttpMethod.POST|HttpMethod.POST>,
            createHttpEntity("no", "usernamepassword", "/test", <http://HttpMethod.POST|HttpMethod.POST>, Collections.emptyMap()),
            Object.class);

        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
    }
}
The used DTO:
Copy code
import java.util.Map;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.http.HttpMethod;

@Data
@AllArgsConstructor
public class ProxyRequestDto {

    private @NotNull(message = "Resource must not be null") String resource;
    private @NotNull(message = "Method must not be null") HttpMethod method;
    private Map<String, Object> body;
}
d
I would guess this is more related to the jackson version referenced in spring than to wiremock - but it's just a guess. Maybe it helps to add a Noargs constructor - or use a builder:
Copy code
@Jacksonized
@Builder
@NoArgsConstructor
d
I tried to with loading current version 2.15.2 of jackson-databind, -datatype-jsr310, -datatype-jdk8 and with each combination if the suggested annotations, unfortunately with no effect.
d
can you create a minimal setup to reproduce it and push it to github?
d
The console output:
Copy code
2023-07-28T10:39:39.871+02:00  INFO 35314 --- [           main] org.eclipse.jetty.server.Server          : Stopped Server@64dfb31d{STOPPING}[11.0.13,sto=0]
2023-07-28T10:39:39.877+02:00  INFO 35314 --- [           main] o.e.jetty.server.AbstractConnector       : Stopped ServerConnector@5cf0673d{HTTP/1.1, (http/1.1)}{0.0.0.0:0}
2023-07-28T10:39:39.881+02:00  INFO 35314 --- [           main] o.e.j.s.h.ContextHandler.application     : Destroying Spring FrameworkServlet 'dispatcherServlet'
2023-07-28T10:39:39.882+02:00  INFO 35314 --- [           main] o.e.jetty.server.handler.ContextHandler  : Stopped o.s.b.w.e.j.JettyEmbeddedWebAppContext@769b0752{application,/,[file:///private/var/folders/n8/k_rcy5wj6jzfrtdlqprdd0th0000gn/T/jetty-docbase.0.6202064899982443399/],STOPPED}
[ERROR] Tests run: 9, Failures: 5, Errors: 0, Skipped: 0, Time elapsed: 7.558 s <<< FAILURE! - in com.xxx.malcolm.MalcolmIT
[ERROR] responseIsProxiedWhenRequestFailed  Time elapsed: 0.288 s  <<< FAILURE!
org.opentest4j.AssertionFailedError: 
expected: 400 BAD_REQUEST
 but was: 500 INTERNAL_SERVER_ERROR
	at com.xxx.malcolm.MalcolmIT.responseIsProxiedWhenRequestFailed(MalcolmIT.java:295)
[ERROR] withNoConfiguredUsernameAndPassword  Time elapsed: 0.014 s  <<< FAILURE!
org.opentest4j.AssertionFailedError: 
expected: 401 UNAUTHORIZED
 but was: 500 INTERNAL_SERVER_ERROR
	at com.xxx.malcolm.MalcolmIT.withNoConfiguredUsernameAndPassword(MalcolmIT.java:100)
[ERROR] withInvalidUsernameAndPassword  Time elapsed: 0.013 s  <<< FAILURE!
org.opentest4j.AssertionFailedError: 
expected: 401 UNAUTHORIZED
 but was: 500 INTERNAL_SERVER_ERROR
	at com.xxx.malcolm.MalcolmIT.withInvalidUsernameAndPassword(MalcolmIT.java:119)
[ERROR] authenticationSuccessful  Time elapsed: 0.013 s  <<< FAILURE!
org.opentest4j.AssertionFailedError: 
expected: 200 OK
 but was: 500 INTERNAL_SERVER_ERROR
	at com.xxx.malcolm.MalcolmIT.authenticationSuccessful(MalcolmIT.java:181)
[ERROR] responseIsProxiedWhenRequestIsSuccessful  Time elapsed: 0.013 s  <<< FAILURE!
org.opentest4j.AssertionFailedError: 
expected: 200 OK
 but was: 500 INTERNAL_SERVER_ERROR
	at com.xxx.malcolm.MalcolmIT.responseIsProxiedWhenRequestIsSuccessful(MalcolmIT.java:263)
[INFO] 
[INFO] Results:
[INFO] 
[ERROR] Failures: 
[ERROR]   MalcolmIT.authenticationSuccessful:181 
expected: 200 OK
 but was: 500 INTERNAL_SERVER_ERROR
[ERROR]   MalcolmIT.responseIsProxiedWhenRequestFailed:295 
expected: 400 BAD_REQUEST
 but was: 500 INTERNAL_SERVER_ERROR
[ERROR]   MalcolmIT.responseIsProxiedWhenRequestIsSuccessful:263 
expected: 200 OK
 but was: 500 INTERNAL_SERVER_ERROR
[ERROR]   MalcolmIT.withInvalidUsernameAndPassword:119 
expected: 401 UNAUTHORIZED
 but was: 500 INTERNAL_SERVER_ERROR
[ERROR]   MalcolmIT.withNoConfiguredUsernameAndPassword:100 
expected: 401 UNAUTHORIZED
 but was: 500 INTERNAL_SERVER_ERROR
[INFO] 
[ERROR] Tests run: 9, Failures: 5, Errors: 0, Skipped: 0
[INFO]
429 Views