S SmartDocs
系列: Bridget java 200 行 · 更新于 2026-04-14

PaymentGatewayServiceTest.java

Bridget/payment-gateway-challenge-java/src/test/java/com/checkout/payment/gateway/service/PaymentGatewayServiceTest.java

package com.checkout.payment.gateway.service;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.checkout.payment.gateway.enums.PaymentStatus;
import com.checkout.payment.gateway.exception.BankErrorException;
import com.checkout.payment.gateway.exception.EventProcessingException;
import com.checkout.payment.gateway.model.BankPaymentRequest;
import com.checkout.payment.gateway.model.BankPaymentResponse;
import com.checkout.payment.gateway.model.PaymentMapper;
import com.checkout.payment.gateway.model.PostPaymentRequest;
import com.checkout.payment.gateway.model.PostPaymentResponse;
import com.checkout.payment.gateway.repository.PaymentsRepository;
import java.util.Optional;
import java.util.UUID;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.HttpStatus;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestTemplate;

@ExtendWith(MockitoExtension.class)
class PaymentGatewayServiceTest {

  private static final String BANK_URL = "http://localhost:8080/payments";

  @Mock
  private PaymentsRepository paymentsRepository;
  @Mock
  private RestTemplate restTemplate;

  private PaymentGatewayService paymentGatewayService;

  @BeforeEach
  void setUp() {
    paymentGatewayService = new PaymentGatewayService(paymentsRepository, restTemplate, BANK_URL);
  }

  @Test
  void shouldReturnPaymentWhenIdExists() {
    PostPaymentResponse payment =
        PostPaymentResponse.builder()
            .cardNumberLastFour("4321")
            .id(UUID.randomUUID())
            .amount(10)
            .currency("USD")
            .status(PaymentStatus.AUTHORIZED)
            .expiryYear(2024)
            .expiryMonth(12)
            .build();
    when(paymentsRepository.get(payment.getId())).thenReturn(Optional.of(payment));

    assertEquals(
        PaymentMapper.toGetResponse(payment), paymentGatewayService.getPaymentById(payment.getId()));
  }

  @Test
  void shouldThrowExceptionWhenIdNotExists() {
    UUID id = UUID.randomUUID();
    when(paymentsRepository.get(id)).thenReturn(Optional.empty());

    assertThrows(EventProcessingException.class, () -> paymentGatewayService.getPaymentById(id));
  }

  @Test
  void shouldReturnAuthorizedWhenBankAuthorized() {
    BankPaymentRequest request =
        BankPaymentRequest.builder()
            .cardNumber("2222405343248877")
            .expiryDate("04/2025")
            .currency("GBP")
            .amount(100)
            .cvv("123")
            .build();
    when(restTemplate.postForObject(eq(BANK_URL), eq(request), eq(BankPaymentResponse.class)))
        .thenReturn(
            BankPaymentResponse.builder()
                .authorized(true)
                .authorizationCode("123456")
                .build());

    BankPaymentResponse response = paymentGatewayService.sendPaymentRequestToBank(request);

    assertTrue(response.isAuthorized());
    verify(restTemplate).postForObject(eq(BANK_URL), eq(request), eq(BankPaymentResponse.class));
  }

  @Test
  void shouldThrowExceptionWhenBankServiceUnavailable() {
    BankPaymentRequest request =
        BankPaymentRequest.builder()
            .cardNumber("2222405343248870")
            .expiryDate("04/2025")
            .currency("GBP")
            .amount(100)
            .cvv("123")
            .build();
    when(restTemplate.postForObject(eq(BANK_URL), eq(request), eq(BankPaymentResponse.class)))
        .thenThrow(new HttpServerErrorException(HttpStatus.SERVICE_UNAVAILABLE));

    assertThrows(BankErrorException.class, () -> paymentGatewayService.sendPaymentRequestToBank(request));
  }

  @Test
  void shouldThrowBankErrorExceptionWhenBankReturnsBadRequest() {
    BankPaymentRequest request =
        BankPaymentRequest.builder()
            .cardNumber("2222405343248870")
            .expiryDate("04/2025")
            .currency("GBP")
            .amount(100)
            .cvv("123")
            .build();
    when(restTemplate.postForObject(eq(BANK_URL), eq(request), eq(BankPaymentResponse.class)))
        .thenThrow(new HttpClientErrorException(HttpStatus.BAD_REQUEST));

    BankErrorException ex =
        assertThrows(
            BankErrorException.class, () -> paymentGatewayService.sendPaymentRequestToBank(request));
    assertEquals(400, ex.getStatusCode().value());
  }

  @Test
  void shouldMaskCardNumberWhenGeneratingResponse() {
    PostPaymentRequest request =
        PostPaymentRequest.builder()
            .cardNumber("2222405343248878")
            .amount(10)
            .currency("USD")
            .expiryYear(2024)
            .expiryMonth(12)
            .cvv("123")
            .build();
    ArgumentCaptor<BankPaymentRequest> bankReq = ArgumentCaptor.forClass(BankPaymentRequest.class);
    when(restTemplate.postForObject(eq(BANK_URL), bankReq.capture(), eq(BankPaymentResponse.class)))
        .thenReturn(
            BankPaymentResponse.builder()
                .authorized(true)
                .authorizationCode("123456")
                .build());

    assertEquals("8878", paymentGatewayService.createPayment(request).getCardNumberLastFour());
    verify(paymentsRepository).add(any(PostPaymentResponse.class));
  }

  @Test
  void shouldReturnAuthorizedStatusWhenBankAuthorized() {
    PostPaymentRequest request =
        PostPaymentRequest.builder()
            .cardNumber("2222405343248878")
            .amount(10)
            .currency("USD")
            .expiryYear(2024)
            .expiryMonth(12)
            .cvv("123")
            .build();
    when(restTemplate.postForObject(eq(BANK_URL), any(BankPaymentRequest.class), eq(BankPaymentResponse.class)))
        .thenReturn(
            BankPaymentResponse.builder()
                .authorized(true)
                .authorizationCode("123456")
                .build());

    PostPaymentResponse result = paymentGatewayService.processPayment(request);
    assertEquals(PaymentStatus.AUTHORIZED, result.getStatus());
  }

  @Test
  void shouldReturnDeclinedStatusWhenBankNotAuthorized() {
    PostPaymentRequest request =
        PostPaymentRequest.builder()
            .cardNumber("2222405343248878")
            .amount(10)
            .currency("USD")
            .expiryYear(2024)
            .expiryMonth(12)
            .cvv("123")
            .build();
    when(restTemplate.postForObject(eq(BANK_URL), any(BankPaymentRequest.class), eq(BankPaymentResponse.class)))
        .thenReturn(
            BankPaymentResponse.builder()
                .authorized(false)
                .authorizationCode("")
                .build());

    PostPaymentResponse result = paymentGatewayService.processPayment(request);
    assertEquals(PaymentStatus.DECLINED, result.getStatus());
  }
}

相关文章

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).

阅读文章 →