【问题标题】:How to mock a static method from JMockit如何从 JMockit 模拟静态方法
【发布时间】:2014-12-12 01:08:18
【问题描述】:

我有一个静态方法,它将从类中的测试方法中调用,如下所示

public class MyClass
{
   private static boolean mockMethod( String input )
    {
       boolean value;
       //do something to value
       return value; 
    }

    public static boolean methodToTest()
    {
       boolean getVal = mockMethod( "input" );
       //do something to getVal
       return getVal; 
    }
}

我想通过模拟 mockMethod 为方法 methodToTest 编写一个测试用例。 尝试如下,它没有给出任何输出

@Before
public void init()
{
    Mockit.setUpMock( MyClass.class, MyClassMocked.class );
}

public static class MyClassMocked extends MockUp<MyClass>
{
    @Mock
    private static boolean mockMethod( String input )
    {
        return true;
    }
}

@Test
public void testMethodToTest()
{
    assertTrue( ( MyClass.methodToTest() );
} 

【问题讨论】:

    标签: java unit-testing testing jmockit


    【解决方案1】:

    模拟你的静态方法:

    new MockUp<MyClass>()
    {
        @Mock
        boolean mockMethod( String input ) // no access modifier required
        {
            return true; 
        }
    };
    

    【讨论】:

    • 如何验证通话?
    【解决方案2】:

    模拟静态私有方法:

    @Mocked({"mockMethod"})
    MyClass myClass;
    
    String result;
    
    @Before
    public void init()
    {
        new Expectations(myClass)
        {
            {
                invoke(MyClass.class, "mockMethod", anyString);
                returns(result);
            }
        }
    }
    
    @Test
    public void testMethodToTest()
    {
        result = "true"; // Replace result with what you want to test...
        assertTrue( ( MyClass.methodToTest() );
    } 
    

    来自 JavaDoc:

    Object mockit.Invocations.invoke(Class methodOwner, String methodName, Object... methodArgs)

    使用给定的参数列表指定对给定静态方法的预期调用。

    【讨论】:

    • 由于这里缺少导入:我猜 invoke() 方法是 Deencapsulation.invoke() 的静态导入。万一其他人一开始想知道...
    【解决方案3】:

    还有另一种使用 JMockit 模拟静态方法的方法(使用 Delegate 类)。我觉得它更方便、更优雅。

    public class Service {
      public String addSuffix(String str) { // method to be tested
        return Utils.staticMethod(str);
      }
    }
    

    public class Utils {
      public static String staticMethod(String s) { // method to be mocked
        String suffix = DatabaseManager.findSuffix("default_suffix");
        return s.concat(suffix);
      }
    }
    

    public class Test {
    
      @Tested
      Service service;
    
      @Mocked
      Utils utils; // @Mocked will make sure all methods will be mocked (including static methods)
    
      @Test
      public void test() {
        new Expectations {{
          Utils.staticMethod(anyString); times = 1; result = new Delegate() {
            public static String staticMethod(String s) { // should have the same signature (method name and parameters) as Utils#staticMethod
              return ""; // provide custom implementation for your Utils#staticMethod
            }
          }
        }}
        
        service.addSuffix("test_value");
    
        new Verifications {{
          String s;
          Utils.staticMethod(s = withCapture()); times = 1;
          assertEquals("test_value", s); // assert that Service#addSuffix propagated "test_value" to Utils#staticMethod
        }}
      }
    }
    

    参考:

    https://jmockit.github.io/tutorial/Mocking.html#delegates https://jmockit.github.io/tutorial/Mocking.html#withCapture

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-21
      • 2013-07-14
      相关资源
      最近更新 更多