测试调用本机方法的代码

发布于 2024-10-16 06:53:10 字数 772 浏览 2 评论 0原文

我有一个这样的类:

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

I have a class like this:

public final class Foo
{
    public native int getBar();

    public String toString()
    {
        return "Bar: " + getBar();
    }
}

Please note that getBar() is implemented with JNI and that the class is final. I want to write a junit test to test the toString() method. For this I need to mock the getBar() method and then run the original toString() method to check the output.

My first thought was that this must be impossible but then I found PowerMock which supports testing final classes and native methods according to the feature list. But so far I had no success with it. The best thing I managed was mocking the complete class but then the test tested the mocked toString() method instead of the real one which doesn't make much sense.

So how can I use PowerMock to test this toString() method from above? I prefer using PowerMock with Mockito but if this is not possible I have no problem with using EasyMock instead.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

九厘米的零° 2024-10-23 06:53:10

找到了。我的做法是正确的。我唯一错过的是告诉模拟对象在调用 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());
    }
}

Found it. The way I was doing it was correct. The only thing I missed was telling the mock object to call the original method when toString was called(). So it works like this:

@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());
    }
}
梦言归人 2024-10-23 06:53:10

或者将 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());
    }
}

Or use JMockit with dynamic partial mocking:

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());
    }
}
生来就爱笑 2024-10-23 06:53:10

或者使用策略模式

    public final class Foo
    {
        public IBarStrategy barStrategy;

        ......
    }

    interface IBarStrategy{
        int getBar();
    }

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

Or use Strategy Pattern:

    public final class Foo
    {
        public IBarStrategy barStrategy;

        ......
    }

    interface IBarStrategy{
        int getBar();
    }

When unit test, inject a mock IBarStrategy instance, then you could test class Foo.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文