【问题标题】:Testing code which calls native methods测试调用本机方法的代码
【发布时间】:2011-06-22 10:05:15
【问题描述】:

我有这样的课:

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

【问题讨论】:

    标签: java junit easymock mockito powermock


    【解决方案1】:

    找到了。我这样做的方式是正确的。我唯一错过的是在调用 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());
        }
    }
    

    【讨论】:

    • 嗨...我不能添加“when()”..为什么..?你能告诉我使用 Easymock 吗
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      或者使用策略模式

          public final class Foo
          {
              public IBarStrategy barStrategy;
      
              ......
          }
      
          interface IBarStrategy{
              int getBar();
          }
      

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

      【讨论】:

      • 依赖注入对于代码重用和模块化来说是一件好事,但如果不需要,那么我为什么要增加复杂性并放松我的类的 API 只是为了可测试性?但这不是重点。因此,假设我无法更改测试主题,因此无法将本机方法提取到接口中。
      • 这样做实际上并没有增加复杂性。您只是通过不这样做来隐藏复杂性。你应该从设计可测试性开始
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-21
      • 2011-12-24
      • 1970-01-01
      • 2011-02-12
      • 1970-01-01
      • 1970-01-01
      • 2018-03-21
      相关资源
      最近更新 更多