私のシナリオは以下の通りです
class SuperClass{
public void run(){
System.out.println("I am running in Super class");
}
}
class ChildClass extends SuperClass{
public void childRunner(){
System.out.println("Step 1");
System.out.println("Step 2");
**run();**
System.out.println("Last Step");
}
}
ChildClass
のchildRunner()
メソッドをモックしたいのですが、このメソッドは内部的にスーパークラスメソッドを呼び出しているため、run()
をモックする方法に関するヘルプ/コードが必要ですChildClass
のchildRunner()
メソッドに存在するメソッド。
理想的には、「継承よりも構成を優先する」必要があります。
このオプションがない場合は、doNothing
を使用できます。これは、基本的に、モック/スパイオブジェクトのメソッドが呼び出されたときにMockitoに何もしないように指示します。これも議論されました here
次のコード例は役立つはずです
@Test
public void tst() {
ChildClass ch = Mockito.spy(new ChildClass());
Mockito.doNothing().when((SuperClass)ch).run();
ch.childRunner();
}
class SuperClass{
public void run(){
System.out.println("I am running in Super class");
}
}
class ChildClass extends SuperClass{
public void childRunner(){
System.out.println("Step 1");
run();
System.out.println("Last Step");
}
}
出力:
Step 1
Last Step
Super.run();を使用する場合。これはうまくいきません
これは、別のクラスを拡張し、他の依存関係があるクラスの例です。この場合、スーパークラスの呼び出しを他のメソッドに移動し、スーパークラスの呼び出し元のメソッドをモックします。
class Child extends Parent {
@Autowired
private Dependicy d;
public Authentication authenticate(Authentication auth) {
the code to be tested...
superAuthenticate(auth);// the code that I don't want to deal with it.
return auth;
}
protected Authentication superAuthenticate(Authentication auth) {
return super.authenticate(auth);
}
}
上記のように、authenticateメソッドはいくつかのロジックを実行してからスーパークラスのメソッドを呼び出します。そのため、スーパークラスの呼び出しをモックして、独自のコードブロックをテストします。これが私のテストクラスです:
@RunWith(MockitoJUnitRunner.class)
public class ChildTest {
@Mock
private Dependicy d;
@InjectMocks
private Child child = new Child();
@Test
public void testSomething() {
Child spy = Mockito.spy(child);
when(d.aMethod(aParam)).thenReturn(aResult);
doReturn(usefulResult).when(spy).superAuthenticate(any());
Authentication result = spy.authenticate(auth);
assertThat(result).isNotNull;
}
}