我有一个这样的课程:
public final class Foo
{
public native int getBar();
public String toString()
{
return "Bar: " + getBar();
}
}
请注意 getBar()是使用JNI实现的,并且该类是 final 。我想编写一个junit测试来测试 toString()方法。为此,我需要模拟 getBar()方法,然后运行原始的 toString()方法来检查输出。
我的第一个想法是,这一定是不可能的,但后来我发现PowerMock支持根据功能列表测试最终类和本机方法。但到目前为止,我没有成功。我管理的最好的事情是嘲笑完整的类,但测试测试了模拟的 toString()方法,而不是真正的方法。
那么如何使用PowerMock从上面测试这个 toString()方法呢?我更喜欢将PowerMock与Mockito一起使用,但如果不可行,我可以使用EasyMock来解决问题。
答案 0 :(得分:8)
找到它。我这样做的方式是正确的。我唯一遗漏的是告诉模拟对象在调用toString时调用原始方法()。所以它的工作原理如下:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ Foo.class })
public class FooTest
{
@Test
public void testToString() throws Exception
{
Foo foo = mock(Foo.class);
when(foo.getBar()).thenReturn(42);
when(foo.toString()).thenCallRealMethod();
assertEquals("Bar: 42", foo.toString());
}
}
答案 1 :(得分:3)
或者将JMockit与动态部分模拟一起使用:
import org.junit.*;
import mockit.*;
public class FooTest
{
@Test
public void testToString()
{
final Foo foo = new Foo();
new Expectations(foo) {{ foo.getBar(); result = 42; }};
assertEquals("Bar: 42", foo.toString());
}
}
答案 2 :(得分:1)
或使用策略模式:
public final class Foo
{
public IBarStrategy barStrategy;
......
}
interface IBarStrategy{
int getBar();
}
进行单元测试时,注入模拟IBarStrategy
实例,然后可以测试类Foo
。