13

我有这样的课:

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来代替。

4

3 回答 3

9

找到了。我这样做的方式是正确的。我唯一错过的是在调用 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());
    }
}
于 2011-02-06T22:04:38.457 回答
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());
    }
}
于 2011-02-11T15:16:04.933 回答
1

或使用策略模式

    public final class Foo
    {
        public IBarStrategy barStrategy;

        ......
    }

    interface IBarStrategy{
        int getBar();
    }

单元测试时,注入一个模拟IBarStrategy实例,然后你可以测试 class Foo

于 2011-02-07T04:31:10.303 回答