如何从JMockit模拟静态方法

Ros*_*nck 19 java testing unit-testing jmockit

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

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; 
    }
}
Run Code Online (Sandbox Code Playgroud)

我想通过模拟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() );
} 
Run Code Online (Sandbox Code Playgroud)

jch*_*n86 32

要模拟静态方法:

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

  • 如何验证通话内容? (2认同)

小智 8

要模拟静态私有方法:

@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() );
} 
Run Code Online (Sandbox Code Playgroud)

来自JavaDoc:

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

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

  • 由于这里缺少导入:我猜 invoke() 方法是 Deencapsulation.invoke() 的静态导入。万一其他人一开始想知道...... (2认同)

Eug*_*yuk 5

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

public class Service {
  public String addSuffix(String str) { // method to be tested
    return Utils.staticMethod(str);
  }
}
Run Code Online (Sandbox Code Playgroud)
public class Utils {
  public static String staticMethod(String s) { // method to be mocked
    String suffix = DatabaseManager.findSuffix("default_suffix");
    return s.concat(suffix);
  }
}
Run Code Online (Sandbox Code Playgroud)
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 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
    }}
  }
}
Run Code Online (Sandbox Code Playgroud)

参考:

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