模拟静态类

时间:2017-01-23 10:37:05

标签: java unit-testing mockito powermock

我在类中有一个实例化静态类实例并在其上调用操作的方法。

public class SomeClass {
    public void someMethod() {
       MyClass.MyStaticClass myStaticClassInstance =
          new MyClass.MyStaticClass( arg1, arg2, arg3 );
       myStaticClassInstance.callSomeMethod();
    }
}

public class MyClass {

   public static class MyStaticClass {

      public MyStaticClass( Object arg1, Object arg2, Object arg3 ) {
      }

      public void callSomeMethod() {
      }
   }
}

如何模拟静态类instanciation,这样我可以在不经过静态类构造函数的情况下模拟callSomeMethod()

3 个答案:

答案 0 :(得分:1)

您可以通过模拟静态内部类的实例化来使用PowerMock来完成此操作。这可以通过准备实际实例化静态内部类的类来完成,所以在这里它将是您定义方法someMethod()的类。

假设someMethod()已定义到类MyOtherClass中并且不返回任何内容,那么您的测试类将是这样的:

@RunWith(PowerMockRunner.class) // The runner of PowerMock
@PrepareForTest(MyOtherClass.class) // the class to prepare
public class MyClassTest {

    @Test
    public void test() throws Exception {
        // The mock of your static inner class to return
        MyClass.MyStaticClass mock = Mockito.mock(MyClass.MyStaticClass.class);
        // Mock the call of callSomeMethod()
        PowerMockito.doAnswer(
            new Answer<Void>() {
                @Override
                public Void answer(final InvocationOnMock invocation) throws Throwable {
                    // Do something here as new implementation of callSomeMethod
                    System.out.println("My new Answer");
                    return null;
                }
            }
        ).when(mock).callSomeMethod();
        // Return your mock in case we instantiate MyClass.MyStaticClass in 
        // the prepared class with any arguments  
        PowerMockito.whenNew(MyClass.MyStaticClass.class)
            .withArguments(Matchers.any(), Matchers.any(), Matchers.any())
            .thenReturn(mock);

        // The code that will call someMethod
        MyOtherClass mc = new MyOtherClass();
        mc.someMethod();
    }
}

假设我的班级MyClass看起来像这样:

public class MyClass {

    public static class MyStaticClass {
        public MyStaticClass(Object arg1, Object arg2, Object arg3) {
            System.out.println("Called constructor");
        }

        public void callSomeMethod() {
            System.out.println("callSomeMethod");
        }
    }
}

我的班级MyOtherClass看起来像这样:

public class MyOtherClass {
    public void someMethod() {
        MyClass.MyStaticClass myStaticClassInstance = new MyClass.MyStaticClass(
            new Object(), new Object(), new Object()
        );
        myStaticClassInstance.callSomeMethod();
    }
}

如果我开始测试,我会按预期得到:

My new Answer

而不是我默认得到的东西:

Called constructor
callSomeMethod

有关how to constructions of new objects的更多详情。

答案 1 :(得分:0)

你可以将PowerMockito与Mockito一起使用来完成这件事。

payload = '{{ "language":"fr","fileName":"{0}","folderId":3309569 }}'.format(filename) 

希望这会有所帮助。快乐的编码!

答案 2 :(得分:0)

我写了一个更简单的工具,用于嘲笑通常不可模仿的东西&#39;在https://github.com/iirekm/misc/tree/master/ajmock

您的代码可能如下所示:

```     公共类MyClassTest {

@Test
public void test() throws Exception {
    MyClass.MyStaticClass mock = Mockito.mock(MyClass.MyStaticClass.class);
    when(() -> mock.callSomeMethod()).thenAnswer(() -> ...);

    when(() -> new MyClass.MyStaticClass(any(), any(), any())).thenReturn(mock);

    // The code that will call someMethod
    MyOtherClass mc = new MyOtherClass();
    mc.someMethod();
}

}

```