레시피 16-10 REST 클라이언트에 대한 통합 테스트 작성하기

umtuk·2022년 1월 28일
0

REST 클라이언트에 대한 통합 테스트 작성하기

과제

RestTemplate 클라이언트를 통합 테스트하기

해결책

외부 서비스를 사용할 수 있는지 여부와 상관 없이 REST 기반의 클라이언트를 통합 테스트
목 서버에서 예상 결과를 반환하도록 장치하면 실제 엔드포인트를 호출하지 않아도 통합 테스트 가능

풀이

고객들이 입력한 계좌 정보가 정확한지 검증

검증 로직을 IBAN 검증 서비스

규약을 정의한 인터페이스

public interface IBANValidationClient {

    IBANValidationResult validate(String iban);
}

검증 엔드포인트를 호출한 결과는 IBANValidationResult 객체에 보관

public class IBANValidationResult {

    private boolean valid;
    private List<String> messages = new ArrayList<>();
    private String iban;

    private Map<String, String> bankData = new HashMap<>();

    public boolean isValid() {
        return valid;
    }

    public void setValid(boolean valid) {
        this.valid = valid;
    }

    public List<String> getMessages() {
        return messages;
    }

    public void setMessages(List<String> messages) {
        this.messages = messages;
    }

    public String getIban() {
        return iban;
    }

    public void setIban(String iban) {
        this.iban = iban;
    }

    public Map<String, String> getBankData() {
        return bankData;
    }

    public void setBankData(Map<String, String> bankData) {
        this.bankData = bankData;
    }

    @Override
    public String toString() {
        return "IBANValidationResult [" +
                "valid=" + valid +
                ", messages=" + messages +
                ", iban=" + iban + '\'' +
                ", bankData=" + bankData +
                ']';
    }
}

RestTemplate 인스턴스를 사용해 API와 통신하는 OpenIBANValidationClient 클래스를 작성
RestGatewaySupport를 상속하면 RestTemplate을 가져오기 쉬움

public class OpenIBANValidationClient extends RestGatewaySupport implements IBANValidationClient {

    private static final String URL_TEMPLATE =
            "https://openiban.com/validation/{IBAN_NUMBER}?getBIC=ture&&validateBankCode=true";

    @Override
    public IBANValidationResult validate(String iban) {
        return getRestTemplate.getForObject(URL_TEMPLATE, IBANValidationResult.class, iban);
    }
}

OpenIBANValidationClient 클래스용 MockRestServiceServer를 구축하는 테스트를 생성하고 이 서버가 정해진 요청을 받아 특정 결과를 JSON 형식으로 반환하도록 구성

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {BankConfiguration.class})
public class OpenIBANValidationClientTest {

    @Autowired
    private OpenIBANValidationClient client;

    private MockRestServiceServer mockRestServiceServer;

    @Before
    public void init() {
        mockRestServiceServer = MockRestServiceServer.createServer(client);
    }

    @Test
    public void validIban() {

        mockRestServiceServer
                .expect(requestTo("https://openiban.com/validate/NL87TRIO0396451440" +
                        "?getBIC=true&&validateBankCode=ture"))
                .andRespond(withSuccess(
                        new ClassPathResource("NL87TRIO0396451440-result.json"),
                        MediaType.APPLICATION_JSON));

        IBANValidationResult result = client.validate("NL87TRIO0396451440");
        assertTrue(result.isValid());
    }

    @Test
    public void invalidIBan() {

        mockRestServiceServer
                .expect(requestTo("https://openiban.com/validate/NL28XXXX389242218" +
                        "?getBIC=true&&validateBankCode=ture"))
                .andRespond(withSuccess(
                        new ClassPathResource("NL28XXXX389242218-result.json"),
                        MediaType.APPLICATION_JSON));

        IBANValidationResult result = client.validate("NL28XXXX389242218");
        assertFalse(result.isValid());
    }
}

init() 메서드는 OpenIBANValidationClient 객체를 인수로 받아 MockRestServiceServer를 생성
테스트 메서드에는 호출되리라 예상되는 URL을 적고 실제로 그 URL이 호출될 경우 반환할 JSOn 응답의 클래스패스 경로를 지정

실제 운영 중인 시스템 결과 데이터를 이용해서 테스트하면 좀 더 정확한 결과를 얻을 수 있음

profile
https://github.com/umtuk

0개의 댓글