테스트 슬라이드

  • 스프링 부트 1.4 이후에는 애플리케이션을 구성하는 레이어의 일부만 선택적으로 자동 설절할 수 있는 테스트 슬라익스 개념이 도입
  • 테스트 슬라이스를 활용하면 진행중인 프로젝트를 다른 스타터 프로젝트로 쉽게 교체할수 있다. 스프링 데이터 jpa를 스프링 데이터 몽고디비로 교체하더라도 스프링 데이터와 관계 없는 통합 테스트에는 아무런 영향을 미치지 않는다.
    • (스프링 데이터 jpa에서는 entity를 스프링 데이터 몽고디비에서는 document라는 어노테이션을 쓴다.)

모의 기법 활용(mocking 기법) or 목 기법

모의 기법은 단위 테스트를 다루는 컨텍스트에서 통용되는 용어이다. 모듈 내에서 협력하는 컴포넌트를 우리가 원하는 방식으로 동작하도록 제어할 수 있는 모의 객체로 대체하면 테스트 중인 시스템과 협력하는 컴포넌트를 격리할수 있다.
(스프링 컨텍스트가 필요하나 전혀 필요하지 않느냐가 통합테스트와 단위 테스트를 구분하는 기준이 된다는 점은 동일하다 - 전편에도 나와있음)

스프링 부트는 @MockBean 어노테이션을 지원하며 해당 어노테이션은 어플리케이션 컨텍스트에 있는 빈을 대신하는 모의 모키토 빈을 만들고, 어플리케이션 컨텍스트에 있는 원래 빈의 동작을 끄라고 스프링에게 지시한다.

application.yml setting

1
2
3
4
5
6
7
8
9
10
11
12
spring:
jpa:
show_sql: false
database: H2
datasource:
url: jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE
initialize: true
platform: H2
data:
rest:
base-path: /api
user-service.host: ${USER_SERVICE_HOST:localhost:8081}

@MockBean어노테이션으로 UserService와 AccountRepository에 대한 모의빈 생성과 활용

AccountServiceTests

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
31
32
33
34
35
36
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
public class AccountServiceTests {

//유저 서비스를 대신하는 모의 객체를 생성
@MockBean
private UserService userService;

@MockBean
private AccountRepository accountRepository;

private AccountService accountService;

@Before
public void before() {

//모의 객체를 파라미터로 전달하고 새로운 어카운트 서비스 생성
accountService = new AccountService(accountRepository, userService);
}

@Test
public void getUserAccountsReturnsSingleAccount() throws Exception {
given(this.accountRepository.findAccountsByUsername("user")).willReturn(
Collections
.singletonList(new Account("user", new AccountNumber("123456789"))));
given(this.userService.getAuthenticatedUser()).willReturn(
new User(0L, "user", "John", "Doe"));

List<Account> actual = accountService.getUserAccounts();

assertThat(actual).size().isEqualTo(1);
assertThat(actual.get(0).getUsername()).isEqualTo("user");
assertThat(actual.get(0).getAccountNumber()).isEqualTo(
new AccountNumber("123456789"));
}
}

@RunWith(SpringRunner.class)만 붙어 있고 @SpringBootTest 어노테이션이 없으므로 테스트가 실행 될때 애플리케이션 컨텍스트가 로딩되지 않는다. 즉 단위테스트이다.
위의 클래스에서 테스트되는 컴포넌트를 AccountService 빈이고 해당 서비스 빈은 UserSerivce빈을 통해 협력한다.

위의 코드를 돌리면 콘솔에서 문제를 발견 할수 없지만

1
2
3
4
5
6
7
8
9
10
11
 assertThat(actual).size().isEqualTo(1);
위의 코드를 아래와 같이 바꾸게 된다면

assertThat(actual).size().isEqualTo(3);

아래와 같이 확인 할수 있다.
org.junit.ComparisonFailure:
Expected :3
Actual :1

AssertThat 말고도 다양한 방법이 있다. 직접 구글링해서 찾아보도록 하자

<클라우드 네이티브 자바 4장 테스트 참고>