序言(请阅读):
问题是:如何实现这一点(使用 PowerMock )而不会从PowerMock获取异常,说这个类无法实例化,因为它是抽象的:
@PrepareForTest({SocketChannel.class})
@RunWith(PowerMockRunner.class)
public class TestThatUsesSocketChannelChannel
{
replace(method(SocketChannel.class, "read", ByteBuffer.class)).with((proxy, method, args) ->
{
// Line below intercepts the argument and manipulates it
((ByteBuffer) args[0]).clear();
});
// The line below throws an exception (because SocketChannel is abstract)
SocketChannel socketChannel = Whitebox.newInstance(SocketChannel.class);
// Once here, ideally I can continue my test
}
答案 0 :(得分:0)
您可以使用简单的Mockito来模拟抽象类:
AbstractClass theMock = mock(AbstractClass.class);
然后通过PowerMock注入这个抽象类的模拟。
答案 1 :(得分:0)
找到答案:因为SocketChannel是一个抽象类,为了使用Whitebox.newInstance,需要使用ConcreteClassGenerator进行初步步骤。这将创建一个具有空方法实现的SocketChannel的运行时子元素。请注意,在此之前我替换了我关心的方法。结论:这允许我实例化(一个动态)抽象类的子项,而不必显式扩展它。请参阅上面的代码,现在可以使用这样的中间步骤:
@PrepareForTest({SocketChannel.class})
@RunWith(PowerMockRunner.class)
public class TestThatUsesSocketChannelChannel
{
replace(method(SocketChannel.class, "read", ByteBuffer.class)).with((proxy, method, args) ->
{
// Line below intercepts the argument and manipulates it
((ByteBuffer) args[0]).clear();
});
// THIS Fixes it: generate a an on-the-fly class that implements stub methods
// for the ones that are abstract and then (and only then) pass that to Whitebox
Class<?> concreteSocketChannelClass = new ConcreteClassGenerator().createConcreteSubClass(SocketChannel.class);
SocketChannel socketChannel = (SocketChannel) Whitebox.newInstance(concreteSocketChannelClass);
// Once here, ideally I can continue my test
}