Java 如何模拟从抽象类继承的受保护子类方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32073116/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to mock protected subclass method inherited from abstract class?
提问by Evandro Pomatti
How to use Mockito or PowerMock to mock a protected method that is realized by a subclass, but inherited from an abstract super class?
如何使用 Mockito 或 PowerMock 模拟由子类实现但继承自抽象超类的受保护方法?
In other words, I want to test "doSomething" method while mocking the "doSomethingElse".
换句话说,我想在模拟“doSomethingElse”的同时测试“doSomething”方法。
Abstract super class
抽象超类
public abstract class TypeA {
public void doSomething() {
// Calls for subclass behavior
doSomethingElse();
}
protected abstract String doSomethingElse();
}
Subclass implementation
子类实现
public class TypeB extends TypeA {
@Override
protected String doSomethingElse() {
return "this method needs to be mocked";
}
}
Solution
解决方案
Answers given here are correct and will work if classes involved are in the same package.
此处给出的答案是正确的,如果所涉及的类在同一个包中,它们将起作用。
But if different packagesare involved one option is to user PowerMock. The following example worked for me. Of course there might be other ways of doing it, this is one that works.
但是如果涉及不同的包,一种选择是使用 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);
}
}
Note: Tests done using Java 5, jUnit 4.11, Mockito 1.9.0 and PowerMock 1.4.12.
注意:使用 Java 5、jUnit 4.11、Mockito 1.9.0 和 PowerMock 1.4.12 完成的测试。
采纳答案by mszalbach
You can use Mockito.CALLS_REAL_METHODS
when mocking the abstract method. This will call the originals methods of the class and you can mock all abstract methods by yourself.
您可以Mockito.CALLS_REAL_METHODS
在模拟抽象方法时使用。这将调用类的原始方法,您可以自己模拟所有抽象方法。
TypeA typeA = mock(TypeA.class, Mockito.CALLS_REAL_METHODS);
when(typeA.doSomethingElse()).thenReturn("Hello");
typeA.doSomething();
Or you test directly on the TypeB with a spy:
或者你直接用间谍在 TypeB 上测试:
TypeB typeB = spy(new TypeB());
when(typeB.doSomethingElse()).thenReturn("Hello");
typeB.doSomething();
回答by jozzy
You can test your abtract class using mockito in the following way
您可以通过以下方式使用 mockito 测试您的抽象类
TypeA typA = Mockito.mock(TypeA.class, Mockito.CALLS_REAL_METHODS);
when(typA.doSomethingElse()).thenReturn("doSomethingElse");
Assert.assertSomething(typeA.doSomething());
回答by Florian Schaetz
I suggest using Mockito for that:
我建议使用 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();
回答by Affy
To mock methods that returns void in abstract classes we could use:
要模拟在抽象类中返回 void 的方法,我们可以使用:
MyAbstractClass abs = Mockito.mock(MyAbstractClass.class);
Mockito.doNothing().when(abs).myMethod(arg1,arg2....));
We can replace arguments with Mockito.anyString() etc as per requirements.
我们可以根据需要用 Mockito.anyString() 等替换参数。