モックではなく実際のメソッドで呼び出したい典型的なケース
モックではなく実際のメソッドで呼び出したい典型的なケースとしては、メソッドが単なる文字列整形・変換だったり数値計算だったり、他のクラスに依存しないような処理がある。
SomeService
というクラスがあり、SomeRepository
に依存しているとする。SomeService
の各メソッドは基本的にSomeRepository
を通してDBアクセスなどを行なっているとする。各メソッドは当然static
メソッドとしては実装できない。
@Service
@RequiredArgsConstructor
public class SomeService {
private final SomeRepository someRepository;
public int create() {
return someRepository.save();
}
// 略
}
メソッドが単なる文字列整形・変換だったり数値計算だったりして、SomeRepository
には依存しない処理の場合は、static
メソッドとして実装できる。
public static int calc(int param1, int param2) {
// 略
}
Spring BootでServiceクラスを実装する際にstatic
メソッドにすることは通常ないが、このようにstatic
メソッドとしても実装できるようなメソッドは、モック化せず実際の処理を通しても問題ないどころか、逆にテストがわかりやすくなることが多い。
一部のメソッドをモックではなく実際のメソッドで呼び出す
@Spy
一部のメソッドをモックではなく実際のメソッドで呼び出す方法としてMockitoの@Spy
がある。
以下のどちらかの書き方でSomeService
クラスのインスタンスを生成する。
書き方1
@ExtendWith(MockitoExtension.class)
public class SomeControllerTest {
@InjectMocks
SomeController someController;
@Mock
SomeRepository someRepository;
@InjectMocks
@Spy
SomeService someService;
}
書き方2
@ExtendWith(MockitoExtension.class)
public class SomeControllerTest {
@InjectMocks
SomeController someController;
@Mock
SomeRepository someRepository;
@Spy
SomeService someService = new SomeService(someRepository);
}
someService.method1();
のようなメソッド呼び出しがテスト実行対象のメソッド内でされたとき、@Spy
ではdoReturn
などでモック化しない限り、実際のメソッドが実行される。
doCallRealMethod
@Mock
でモック化したインスタンスに対してdoCallRealMethod
を使うことでも、メソッドをモックではなく実際のメソッドで呼び出すことができる。
doCallRealMethod().when(someService).method1(any());
このように書くことで、someService.method1();
のようなメソッド呼び出しがテスト実行対象のメソッド内でされたとき、実際のメソッドが実行される。
@Mock
でSomeService
をモック化するときは、SomeService
が依存しているSomeRepository
について書く必要がない。
@ExtendWith(MockitoExtension.class)
public class SomeControllerTest {
@InjectMocks
SomeController someController;
@Mock
SomeService someService;
}
doCallRealMethod vs @Spy
doCallRealMethod
と@Spy
のどちらを積極的に使用すべきかについては、クラスの各メソッドのどれだけの割合が実際のメソッド呼び出しになるかで決まる。
モック化されるメソッドが大半で1, 2個のメソッドのみが実際のメソッド呼び出しなのであれば、モック化がデフォルトの@Mock
を使用して、1, 2個のメソッドのみdoCallRealMethod
で実際のメソッド呼び出しができるようにすればいい。
反対に、基本的に全て実際のメソッド呼び出しをする中で一部だけモック化したい場合は、@Spy
を使うべき。