이번 시간에는 Spring Boot 1.4부터 추가된 Test를 알아보자

Spring Boot 1.3 에서는 이런 어노테이션을 붙어서 테스트를 진행했다.

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class SimpleTestCase {
}

하지만 1.4.부터는 좀더 심플하게 바뀌었다.

@RunWith(SpringRunner.class)
@SpringBootTest
public class SimpleTestCase{
}

좀더 간판해졌다는걸 알수 있다.
1.4 부터 추가된 @MockBean 이라는 어노테이션이 있다. 가짜 객체를 만들어 테스트할 수 있게 만들어준다. 한번 코드를 보자.

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SpringBootTestApplicationTests {

    @Autowired
    private TestRestTemplate restTemplate;

    @MockBean
    public UserService userService;

    @Test
    public void userRestTemplateTest() throws Exception {
        User user = new User(1L, "wonwoo", "wonwoo@test.com", "123123");
        given(userService.findOne(1L)).willReturn(user);
        ResponseEntity<User> userEntity = this.restTemplate.getForEntity("/findOne/{id}", User.class, 1);
        User body = userEntity.getBody();
        assertThat(body.getName()).isEqualTo("wonwoo");
        assertThat(body.getEmail()).isEqualTo("wonwoo@test.com");
        assertThat(body.getPassword()).isEqualTo("123123");
        assertThat(body.getId()).isEqualTo(1);
    }
}

@Autowired 와 비슷하게 사용하면 된다. @MockBean 어노테이션만 붙어주면 된다. 그럼 실제 객체가 아닌 가짜 객체가 주입된다.
그러고나서 호출할 때와 리턴값을 가짜 객체를 만들어서 넣어주고 호출해주면 된다. 그러면 실제 UserService 호출하는 어느곳에서 가짜객체가 만들어져서 위와 같은 리턴값을 받게된다.
위의 예제는 TestRestTemplate을 이용했는데 MockMvc를 이용해도 된다.

@RunWith(SpringRunner.class)
@WebMvcTest(UserController.class)
public class UserControllerTest {

  @Autowired
  private MockMvc mvc;

  @MockBean
  public UserService userService;

  @Test
  public void userTest() throws Exception {
    given(userService.findOne(1L)).willReturn(new User(1L, "wonwoo", "wonwoo@test.com", "123123"));
    mvc.perform(get("/findOne/{id}", 1L).accept(MediaType.APPLICATION_JSON))
      .andDo(print())
      .andExpect(status().isOk())
      .andExpect(jsonPath("$.id", is(1)))
      .andExpect(jsonPath("$.name", is("wonwoo")))
      .andExpect(jsonPath("$.email", is("wonwoo@test.com")))
      .andExpect(jsonPath("$.password", is("123123")))
      .andExpect(content().json("{'id':1,'name':'wonwoo','email':'wonwoo@test.com','password':'123123'}"));
  }
}

아까의 예제와 비슷하게 UserService에 가짜객체를 주입해서 테스트를 했다. 뭐 나머지는 예전에 테스트 포스팅을 할때 했던거라 굳이 설명하지는 않겠다.

다음은 @DataJpaTest 인데 Jpa를 테스트 할 때 사용하면 될듯하다. 바로 예제를 보자.

@RunWith(SpringRunner.class)
@DataJpaTest
public class UserRepositoryTest {

  @Autowired
  private TestEntityManager entityManager;

  @Autowired
  private UserRepository repository;

  @Test
  public void findByNameTest() {
    this.entityManager.persist(new User("wonwoo", "wonwoo@test.com","123123"));
    User user = this.repository.findByname("wonwoo");
    assertThat(user.getName()).isEqualTo("wonwoo");
    assertThat(user.getEmail()).isEqualTo("wonwoo@test.com");
    assertThat(user.getPassword()).isEqualTo("123123");
    assertThat(user.getId()).isEqualTo(1);
  }
}

TestEntityManager 라는 클래스는 Spring 1.4부터 추가 되었다. 이것은 주입받아서 테스트를 할 수 있다. persist를 해도 실제 디비에는 저장 되지 않는듯 하다. 정말 Test를 위해서 만들어진듯하다. 필자는 @DataJpaTest를 잘 사용하지 않겠지만 나머지 두개는 많이 사용할 듯하다.
이외에도 Json을 테스트 할 수 있는 것들도 존재 한다. 딱히 필자는 필요 없어서 하지는 않았다.
@JsonTest 어노테이션과 JacksonTester클래스를 한번 살펴보면 되겠다. 관심있는 분들은 한번 살펴보면 좋을 것 같다.
필자는 @MockBean 어노테이션이 젤 맘에 든다. 좀 더 쉽게 테스트를 할 수 있어 좋다.
간단한 소스도 여기에 올려놨으니 한번 살펴보면 도움이 많이 될듯하다.