如何从JMockit模拟静态方法

时间:2014-10-16 15:29:00

标签: java unit-testing 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; 
    }
}

我想通过模拟 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() );
} 

3 个答案:

答案 0 :(得分:30)

模拟静态方法:

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

答案 1 :(得分:7)

模拟静态私有方法:

@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)

     

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

答案 2 :(得分:0)

还有另一种使用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