web-dev-qa-db-ja.com

抽象クラスから継承された保護されたサブクラスメソッドをモックする方法は?

MockitoまたはPowerMockを使用して、サブクラスによって実現されるが抽象スーパークラスから継承される保護されたメソッドをモックする方法は?

つまり、「doSomethingElse」をモックしながら「doSomething」メソッドをテストしたいのです。

抽象スーパークラス

public abstract class TypeA {

    public void doSomething() {     

        // Calls for subclass behavior
        doSomethingElse();      
    }

    protected abstract String doSomethingElse();

}

サブクラスの実装

public class TypeB extends TypeA {

    @Override
    protected String doSomethingElse() {
        return "this method needs to be mocked";
    }

}

ソリューション

ここに記載されている回答は正しく、関連するクラスが同じパッケージに含まれている場合に機能します。

しかし、異なるパッケージが関係している場合、1つのオプションはPowerMockを使用することです。次の例は私のために働いた。もちろん、それを行う他の方法があるかもしれません、これはうまくいくものです。

import static org.junit.Assert.assertEquals;
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)
@PrepareForTest({ TypeB.class })
public class TestAbstract {

    @Test
    public void test_UsingPowerMock() throws Exception {
        // Spy a subclass using PowerMock
        TypeB b = PowerMockito.spy(new TypeB());
        String expected = "some value for mock";

        // Mock a method by its name using PowerMock again
        PowerMockito.doReturn(expected).when(b, "doSomethingElse");

        // Calls the 
        String actual = b.doSomething();
        assertEquals(expected, actual);     

    }
}

注:Java 5、jUnit 4.11、Mockito1.9.0およびPowerMock1.4.12。

7
Evandro Pomatti

抽象メソッドをモックするときにMockito.CALLS_REAL_METHODSを使用できます。これにより、クラスの元のメソッドが呼び出され、すべての抽象メソッドを自分でモックできます。

TypeA typeA = mock(TypeA.class, Mockito.CALLS_REAL_METHODS);
when(typeA.doSomethingElse()).thenReturn("Hello");
typeA.doSomething();

または、スパイを使用してTypeBで直接テストします。

TypeB typeB = spy(new TypeB());
when(typeB.doSomethingElse()).thenReturn("Hello");
typeB.doSomething();
5
mszalbach

そのためにMockitoを使用することをお勧めします。

// Create a new Mock
final TypeA a = Mockito.mock(TypeA.class, Mockito.CALLS_REAL_METHODS);

// Call the method
a.doSomething();

// Now verify that our mocked class' method was called
Mockito.verify(a, Mockito.times(1)).doSomethingElse();
4
Florian Schaetz

次の方法でmockitoを使用して抽象クラスをテストできます

TypeA typA = Mockito.mock(TypeA.class, Mockito.CALLS_REAL_METHODS);
when(typA.doSomethingElse()).thenReturn("doSomethingElse");
Assert.assertSomething(typeA.doSomething());
3
jozzy

抽象クラスでvoidを返すメソッドをモックするには、次のように使用できます。

MyAbstractClass abs = Mockito.mock(MyAbstractClass.class);
Mockito.doNothing().when(abs).myMethod(arg1,arg2....));

要件に応じて、引数をMockito.anyString()などに置き換えることができます。

0
Affy