Mockito+PowerMockチートシート

# はじめに
Javaのユニットテストで Mockito + PowerMock でモックする時に、よく使いそうなものをできる限り簡潔にまとめてみます。（随時追記していく予定です）

# 目次
- [MockitoとPowerMockを導入する](#MockitoとPowerMockを導入する)
- [staticメソッドをモック化する](#staticメソッドをモック化する)
- [newされているインスタンスをモック化する](#newされているインスタンスをモック化する)
- [一部のメソッドをモック化する](#一部のメソッドをモック化する)

# MockitoとPowerMockを導入する
Gradleの場合、build.gradleに以下の依存関係を追加します。

```gradle:build.gradle
dependencies {
    testImplementation 'junit:junit:4.12'
    testImplementation "org.mockito:mockito-core:2.28.+"
    testImplementation 'org.powermock:powermock-module-junit4:2.0.2'
    testImplementation 'org.powermock:powermock-api-mockito2:2.0.2'
}
```

# staticメソッドをモック化する
以下のメソッドをテストする場合にメソッドから呼び出しているstaticメソッド「ExampleDBA.findAll()」をモック化してみます。

```java:テスト対象クラス
import java.util.List;

public class ExampleLogic {
    public Integer countExamples() {
        List<ExampleDTO> list = ExampleDBA.findAll();
        return list.size();
    }
}
```

```java:テストクラス
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.powermock.api.mockito.PowerMockito.when;

import java.util.Arrays;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class) //(1)
@PrepareForTest({ ExampleDBA.class }) //(2)
public class ExampleLogicTest {

    ExampleLogic logic = new ExampleLogic();

    @Before
    public void setUp() throws Exception {
        PowerMockito.mockStatic(ExampleDBA.class); //(3)
    }

    @Test
    public void countExamples() {
        List<ExampleDTO> result = Arrays.asList(new ExampleDTO());
        when(ExampleDBA.findAll()).thenReturn(result); //(4)
        assertThat(logic.countExamples(), equalTo(1));
    }
}
```
(1) PowerMockを使う場合に必要なおまじないです。
(2) モック化するstaticメソッドを持つクラスを指定します。
(3) モック化するstaticメソッドを持つクラスを指定します。
(4) staticメソッドが実行された場合の戻り値を指定します。


# newされているインスタンスをモック化する

```java:テスト対象クラス
public class ExampleService {
    public Integer count() {
        ExampleLogic logic = new ExampleLogic();
        return logic.countExamples();
    }
}
```

```java:テストクラス
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.mock;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.powermock.api.mockito.PowerMockito.whenNew;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class) //(1)
@PrepareForTest({ ExampleService.class }) //(2)
public class ExampleServiceTest {

    ExampleService service = new ExampleService(); //(3)

    @Test
    public void count() throws Exception {
        ExampleLogic logic = mock(ExampleLogic.class); //(4)
        whenNew(ExampleLogic.class).withNoArguments().thenReturn(logic); //(5)
        when(logic.countExamples()).thenReturn(0); //(6)

        assertThat(service.count(), equalTo(0));
    }
}
```
(1) PowerMockを使う場合に必要なおまじないです。
(2) テスト対象クラスを指定します。
(3) テスト対象クラスのインスタンスを生成します。
(4) モックオブジェクトを作成します。
(5) newされた時にモックオブジェクトを返すように設定します。
(6) モックオブジェクトのメソッドが呼ばれた際の戻り値を設定します。
(*) モック化対象のオブジェクトをnewする前に(4)〜(6)は実施する必要があります。
　例えば、ExampleServiceのコンストラクタでExampleLogicをnewしている場合、
　ExampleServiceは(6)の後で(3)する必要があります。
 
# 一部のメソッドをモック化する

```java:テスト対象クラス
public class ExampleLogic2 {
    private String privateMethod() {
        return "abc";
    }
    public String publicMethod() {
        String str = privateMethod();
        return str.toUpperCase();
    }
}
```

```java:テストクラス
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.when;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class) //(1)
@PrepareForTest(ExampleLogic2.class) //(2)
public class ExampleLogicTest2 {

    @Test
    public void publicMethod() throws Exception {
        ExampleLogic2 logic = spy(new ExampleLogic2()); //(3)
        when(logic, "privateMethod").thenReturn("str"); //(4)
        assertThat(logic.publicMethod(), equalTo("STR"));
    }
}
```
(1) PowerMockを使う場合に必要なおまじないです。
(2) テスト対象クラスを指定します。
(3) 一部のメソッドをモック化するためテスト対象クラスをnewしてspyを呼び出します。
(4) モック化するメソッド（この例ではprivate）の戻り値を設定します。