S SmartDocs
시리즈: Bridget java 137 줄 · 업데이트 2026-04-18

PaymentGatewayIntegrationTest.java

Bridget/payment_solutions/src/test/java/com/checkout/payment/gateway/integration/PaymentGatewayIntegrationTest.java

package com.checkout.payment.gateway.integration;

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.assertj.core.api.Assertions.assertThat;

import com.checkout.payment.gateway.model.GetPaymentResponse;
import com.checkout.payment.gateway.model.PostPaymentRequest;
import com.checkout.payment.gateway.model.PostPaymentResponse;
import com.checkout.payment.gateway.security.ApiKeyAuthenticationFilter;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import java.util.UUID;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
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.context.ActiveProfiles;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles({"integration"})
@Testcontainers(disabledWithoutDocker = true)
class PaymentGatewayIntegrationTest {

    private static final int BANK_WIREMOCK_PORT = 19100;

    private static final WireMockServer BANK_WIRE_MOCK = new WireMockServer(
            WireMockConfiguration.options().port(BANK_WIREMOCK_PORT));

    @Container
    static final PostgreSQLContainer<?> POSTGRES = new PostgreSQLContainer<>("postgres:15-alpine")
            .withDatabaseName("payment_gateway")
            .withUsername("payment")
            .withPassword("payment");

    static {
        BANK_WIRE_MOCK.start();
    }

    @AfterAll
    static void tearDown() {
        BANK_WIRE_MOCK.stop();
    }

    @DynamicPropertySource
    static void registerProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", POSTGRES::getJdbcUrl);
        registry.add("spring.datasource.username", POSTGRES::getUsername);
        registry.add("spring.datasource.password", POSTGRES::getPassword);
        registry.add("bank.simulator.url", () -> "http://localhost:" + BANK_WIREMOCK_PORT);
        registry.add("gateway.security.enabled", () -> "true");
        registry.add("gateway.security.merchant-api-keys", () -> "integration-merchant-key");
        registry.add("gateway.security.admin-api-keys", () -> "integration-admin-key");
        registry.add("gateway.ratelimit.enabled", () -> "false");
    }

    @LocalServerPort
    private int port;

    @Autowired
    private TestRestTemplate restTemplate;

    @BeforeEach
    void resetBankStub() {
        BANK_WIRE_MOCK.resetAll();
        BANK_WIRE_MOCK.stubFor(post(urlEqualTo("/payments"))
                .willReturn(aResponse()
                        .withStatus(200)
                        .withHeader("Content-Type", "application/json")
                        .withBody("{\"authorized\":true,\"authorization_code\":\""
                                + UUID.randomUUID() + "\"}")));
    }

    @Test
    void postPayment_persistsAndCanBeRetrieved() {
        PostPaymentRequest request = new PostPaymentRequest();
        request.setCardNumber("2222405343248877");
        request.setExpiryMonth(4);
        request.setExpiryYear(2030);
        request.setCurrency("GBP");
        request.setAmount(100);
        request.setCvv("123");

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set(ApiKeyAuthenticationFilter.API_KEY_HEADER, "integration-merchant-key");
        headers.set("Idempotency-Key", UUID.randomUUID().toString());

        String base = "http://localhost:" + port + "/api/v1";
        ResponseEntity<PostPaymentResponse> created = restTemplate.exchange(
                base + "/payments",
                HttpMethod.POST,
                new HttpEntity<>(request, headers),
                PostPaymentResponse.class);

        assertThat(created.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(created.getBody()).isNotNull();
        assertThat(created.getBody().getStatus().getName()).isEqualTo("Authorized");
        UUID id = created.getBody().getId();

        ResponseEntity<GetPaymentResponse> fetched = restTemplate.exchange(
                base + "/payments/" + id,
                HttpMethod.GET,
                new HttpEntity<>(headers),
                GetPaymentResponse.class);

        assertThat(fetched.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(fetched.getBody()).isNotNull();
        assertThat(fetched.getBody().getId()).isEqualTo(id);
        assertThat(fetched.getBody().getAmount()).isEqualTo(100);

        BANK_WIRE_MOCK.verify(postRequestedFor(urlEqualTo("/payments"))
                .withRequestBody(matchingJsonPath("$.card_number", equalTo("2222405343248877")))
                .withRequestBody(matchingJsonPath("$.expiry_date", equalTo("04/2030")))
                .withRequestBody(matchingJsonPath("$.currency", equalTo("GBP")))
                .withRequestBody(matchingJsonPath("$.amount", equalTo("100")))
                .withRequestBody(matchingJsonPath("$.cvv", equalTo("123"))));
    }
}

관련 글

Bridget java 업데이트 2026-03-30

PaymentGatewayApplication.java

PaymentGatewayApplication.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/PaymentGatewayApplication.java).

글 읽기 →
Bridget java 업데이트 2026-03-20

ApplicationConfiguration.java

ApplicationConfiguration.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/configuration/ApplicationConfiguration.java).

글 읽기 →
Bridget java 업데이트 2026-03-30

RequestResponseLogger.java

RequestResponseLogger.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/configuration/RequestResponseLogger.java).

글 읽기 →
Bridget java 업데이트 2026-04-14

PaymentGatewayController.java

PaymentGatewayController.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/controller/PaymentGatewayController.java).

글 읽기 →
Bridget java 업데이트 2026-03-20

PaymentStatus.java

PaymentStatus.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/enums/PaymentStatus.java).

글 읽기 →
Bridget java 업데이트 2026-03-29

BankErrorException.java

BankErrorException.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/exception/BankErrorException.java).

글 읽기 →