Spring Boot + JUnit + Mockitoで単体テストをやる


Spring Boot + MySQLでシンプルなWeb REST APIサーバを実装する - Qiita

Outline

Spring Bootで作成したREST APIのテストを組む。
モックを利用した単体テストをやる。

今回は例として、Service(UserService.java)のテストを組む。
Spring BootとJPAでREST APIを実装する(ドメイン層編) - Qiita

Repositoryをモック化して、Serviceのコードに集中したテストを組む。

Mockito

モック化にはMockitoというライブラリを利用する。
spring-boot-starter-testを利用していればすぐに利用可能。
Mockito framework site

準備

これまでの手順でプロジェクトを作成(Spring Initializr)していれば、特に準備は必要ない。
既にMockitoは利用できるようになっている(spring-boot-starter-test)。

UserServiceTests.java

UserServiceTests.java
package com.example.springapi.domain;

import com.example.springapi.domain.object.User;
import com.example.springapi.domain.repository.UserRepository;
import com.example.springapi.domain.service.UserService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.test.context.junit4.SpringRunner;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(SpringRunner.class)
public class UserServiceTests {

    private final static String TEST_ID = "test_id";
    private final static String TEST_VALUE = "test_value";

    private User testUser;

    @Mock
    private UserRepository userRepository;
    @InjectMocks
    private UserService userService;

    @Before
    public void setup() {
        this.testUser = User.builder()
                .id(TEST_ID)
                .value(TEST_VALUE)
                .build();
    }

    @Test
    public void findById() {

        when(this.userRepository.findById(TEST_ID)).thenReturn(this.testUser);

        User actual = this.userService.findById(TEST_ID);

        assertThat(actual).isEqualTo(this.testUser);

        verify(this.userRepository, times(1)).findById(TEST_ID);
    }

    @Test
    public void save() {

        when(this.userRepository.save(this.testUser)).thenReturn(this.testUser);

        User actual = this.userService.save(this.testUser);

        assertThat(actual).isEqualTo(this.testUser);

        verify(this.userRepository, times(1)).save(this.testUser);
    }

    @Test
    public void deleteById() {

        this.userService.deleteById(TEST_ID);

        verify(this.userRepository, times(1)).deleteById(TEST_ID);
    }
}

@Runwith

JUnitのアノテーション。
テストの実行方法を指定するアノテーション。
これから紹介するMockitoのアノテーションを利用するためには、このアノテーションでMockitoJUnitRunner.classを指定しなければならない。
SpringではSpringRunner.classというものが用意されており、これを利用することでもMockitoを利用することができる。

@Mock

Mockitoのアノテーション。
付与したフィールドにモックインスタンスを生成する。

@InjectMocks

Mockitoのアノテーション。
@Mockのついたインスタンスを注入したインスタンスを生成する。

Mockito.when(), thenReturn()

モック化したインスタンスのメソッドに引数と返り値のペアを定義する。

Mockito.verify()

指定したモックのメソッドが何回呼び出されたかを確認することができる。
最低n回とかいろいろできる。