たとえば、ハンドラーがあります。
_@Component
public class MyHandler {
@AutoWired
private MyDependency myDependency;
public int someMethod() {
...
return anotherMethod();
}
public int anotherMethod() {...}
}
_
それをテストするために、私はこのような何かを書きたいです:
_@RunWith(MockitoJUnitRunner.class}
class MyHandlerTest {
@InjectMocks
private MyHandler myHandler;
@Mock
private MyDependency myDependency;
@Test
public void testSomeMethod() {
when(myHandler.anotherMethod()).thenReturn(1);
assertEquals(myHandler.someMethod() == 1);
}
}
_
しかし、実際にそれをモックしようとすると、anotherMethod()
を呼び出します。 myHandler
でメソッドをモックするにはどうすればよいですか?
まず、MyHandlerメソッドをモックする理由は次のとおりです。すでにanotherMethod()
をテストしており、複雑なロジックを持っているので、なぜ(someMethod()
の一部のように)呼び出している_verify
だけができたら?
次の方法で対応できます。
@RunWith(MockitoJUnitRunner.class}
class MyHandlerTest {
@Spy
@InjectMocks
private MyHandler myHandler;
@Mock
private MyDependency myDependency;
@Test
public void testSomeMethod() {
doReturn(1).when(myHandler).anotherMethod();
assertEquals(myHandler.someMethod() == 1);
verify(myHandler, times(1)).anotherMethod();
}
}
注:「スパイ」オブジェクトの場合、doReturn
の代わりにthenReturn
を使用する必要があります(ほとんど説明はありません here )
コードでは、MyHandlerをまったくテストしていません。テスト対象をモックしたくない、実際のメソッドを呼び出したい。 MyHandlerに依存関係がある場合、それらをモックします。
このようなもの:
public interface MyDependency {
public int otherMethod();
}
public class MyHandler {
@AutoWired
private MyDependency myDependency;
public void someMethod() {
myDependency.otherMethod();
}
}
そしてテスト中:
private MyDependency mockDependency;
private MyHandler realHandler;
@Before
public void setup() {
mockDependency = Mockito.mock(MyDependency.class);
realHandler = new MyHandler();
realhandler.setDependency(mockDependency); //but you might Springify this
}
@Test
public void testSomeMethod() {
//specify behaviour of mock
when(mockDependency.otherMethod()).thenReturn(1);
//really call the method under test
realHandler.someMethod();
}
重要なのは、テスト対象のメソッドを実際に呼び出すことですが、それらが持つ可能性のある依存関係を模倣することです(他のクラスのメソッドの呼び出しなど)
これらの他のクラスがアプリケーションの一部である場合、独自の単体テストがあります。
[〜#〜] note [〜#〜]上記のコードはより多くの注釈で短縮できますが、説明のためにもっと明示的にしたかったのです注釈は:))