티스토리 뷰
이번글에서는 Spring boot 를 이용한 웹서비스 구성 및 TDD 를 이용한 MSA 웹서비스 구현해 보도록 하겠다.
Spring boot 로 웹프로젝트 구성
- SpringBoot initializr : https://start.spring.io/
- SpringBoot 스팩
- 구동
TDD를 통한 Cert(인증) 서버 개발
TDD : 실제 코드 보다 테스트 코드 먼저 작성하며, 테스트를 실패하게 만든 후에 테스트에 성공하는 로직 작성
TDD 가 개발자들에게 좋은 이유 : TDD 로 요구사항에 대해 더 깊이 있게 생각 할 수 있다는 점
테스트코드의 반복적으로 리팩터링하는 생각 vs 테스트만 통과 시키고 나중에 리팩터링 하려는 생각에 균형이 필요함
Cert 로직 개발
- certResDto
package com.sw.cert;
import lombok.Data;
/**
* swCert 인증 DTO
*/
@Data
public class certResDto {
private String certResult; // 인증 결과
}
- cert interface
package com.sw.cert;
public interface CertService {
/*
* 인증키를 조회 하여 인증 결과를 내려줌
*/
certResDto cert(String certKey);
}
- 인증키 랜덤 생성서비스 (GeneratorCertKeyService)
package com.sw.cert;
public interface GeneratorCertKeyService {
/*
* @return 인증키
*/
String generatorCertKey();
}
첫번째 테스트 코드 작성
package com.sw.cert;
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.mock.mockito.MockBean;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.when;
@SpringBootTest
public class CertServiceTest {
@MockBean
private GeneratorCertKeyService generatorCertKeyService;
@Autowired
private CertService certService;
@Test
public void createGeneratorCertKeyTest() {
CertResDto certResDto = new CertResDto();
// given (generatorCertKeyService 가 처음 정상 인증키 2023A, 나중에는 비정상 인증키 2022B를 반환 하도록 설정)
given(generatorCertKeyService.generatorCertKey()).willReturn("2023A", "2023B");
// when
when(certService.cert(generatorCertKeyService.generatorCertKey())).thenReturn(certResDto);
// assert
assertThat(certResDto.getCertResult()).isEqualTo("success");
// when
when(certService.cert(generatorCertKeyService.generatorCertKey())).thenReturn(certResDto);
// assert
assertThat(certResDto.getCertResult()).isEqualTo("fail");
}
}
- 이 테스트에서 중요한건 @MockBean 이다, 해당 어노테이션은 아직 구현되지 않은 GeneratorCertKeyService 인터페이스 맞는 구현 클래스를 찾아서 주입하는 대신 목(mock) 객체를 주입하여, 테스트가 가능하게 한다.
- MockitoBDD 로 generatorCertKeyService.generatorCertKey 를 호출할 때, 어떤 값을 반환할지 미리 정의하고 있다. 리는 행위 주도 개발 (behavior-driven development; BDD) 방식으로 테스트를 더 읽기 쉽게 해주고, 요구사항을 정의하는 데 도움이 된다.
- 위의 테스트를 진행 하면 에러가 발생하는데, 이유는 CertService의 구현체를 만들지 않았기 때문이다. 이게 바로 TDD의 요점 이다. 먼저 요구사항을 테스트로 작성하고 스크럼(Scrum)의 프로덕트 오너(Produect Owner) 같은 비지니스 분석가와 함께 요구사항을 검증 한다.
이제 CertService 를 구현해 보도록 하자
package com.sw.cert;
import org.springframework.stereotype.Service;
@Service
public class CertServiceImpl implements CertService {
/*
* 인증 서비스에서 인증된 key
*/
private final String certKey = "2023A";
@Override public CertResDto cert(String certKey) {
if (this.certKey.equals(certKey)) {
return new CertResDto.CertResDtoBuilder().certResult("success").build();
} else {
return new CertResDto.CertResDtoBuilder().certResult("fail").build();
}
}
}
- 첫번째 테스트 코드 동작시... thenReturn 값이 String 이여 한다는 알수 없는 오류가 발생해서 우선은 아래와 같이 테스트 코드를 수정했다. (나중에 문제점을 찾아 봐야 겠다.)
신규 테스트코드
package com.sw.cert;
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.mock.mockito.MockBean;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
@SpringBootTest
public class CertServiceTest {
@MockBean
private GeneratorCertKeyService generatorCertKeyService;
@Autowired
private CertService certService;
@Test
public void createGeneratorCertKeyTest() {
// 초기화
CertResDto certResDto = new CertResDto("0000");
// given (generatorCertKeyService 가 처음 정상 인증키 2023A, 나중에는 비정상 인증키 2022B를 반환 하도록 설정)
given(generatorCertKeyService.generatorCertKey()).willReturn("2023A", "2023B");
// when
certResDto = certService.cert(generatorCertKeyService.generatorCertKey());
// assert
assertThat(certResDto.getCertResult()).isEqualTo("success");
// when
certResDto = certService.cert(generatorCertKeyService.generatorCertKey());
// assert
assertThat(certResDto.getCertResult()).isEqualTo("fail");
}
}
테스트가 성공 했다. 위의 방법으로 먼저 테스트 코드를 작성하고 로직을 작성하는 방법에 대해서 실습했다. 작성 하면서 느낀 TDD 의 장점을 정리해 보면 아래와 같다.
- 테스트를 작성하면서 요구사항을 코드로 바꿀수 있기 떄문에, 요구사항을 살펴보면서 필요한 것과 필요하지 않은 것에 대해 생각이 가능하다.
- 테스트 코드를 미리 작성하기 때문에, 구현 로직을 미리 분리할수 있으며, 테스트가 된 상태로 개발이 가능하다.
- 랜덤데이터 생성 GeneratorCertKeyService의 구현체를 작성할 필요가 없이 테스트가 가능 하다.
'MSA' 카테고리의 다른 글
타사 MSA 분석하기 (0) | 2023.04.02 |
---|---|
Kafka 를 이용한 msa 서비스 통신 (0) | 2023.02.26 |
Kafka 로컬 연동 및 테스트 (0) | 2023.02.25 |
스프링부트를 활용한 마이크로 서비스 개발_2 (0) | 2023.01.28 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- GateWayApi
- EC2
- data mining
- mongodb
- 웹서비스
- data crawling
- MSA
- AWS
- Python #FastAPI
- MQ
- TDD
- Python
- 웹개발
- 퀜트백
- 테스트
- 테스트 주도 개발
- 테스트주도개발
- 켄트 백
- fastapi
- kafka
- nodejs
- 분산처리
- SpringBoot
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
글 보관함