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 응답의 클래스패스 경로를 지정
실제 운영 중인 시스템 결과 데이터를 이용해서 테스트하면 좀 더 정확한 결과를 얻을 수 있음