Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 模拟静态类_Java_Unit Testing_Mockito_Powermock - Fatal编程技术网

Java 模拟静态类

Java 模拟静态类,java,unit-testing,mockito,powermock,Java,Unit Testing,Mockito,Powermock,我在一个类中有一个方法,它实例化一个静态类实例并对其调用操作 public class SomeClass { public void someMethod() { MyClass.MyStaticClass myStaticClassInstance = new MyClass.MyStaticClass( arg1, arg2, arg3 ); myStaticClassInstance.callSomeMethod(); }

我在一个类中有一个方法,它实例化一个静态类实例并对其调用操作

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() {
      }
   }
}

如何模拟静态类实例,这样我就可以模拟
callsomethod()
,而无需经过静态类构造函数?

您可以通过模拟静态内部类的实例化,使用
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();
    }
}
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");
        }
    }
}
public class MyOtherClass {
    public void someMethod() {
        MyClass.MyStaticClass myStaticClassInstance = new MyClass.MyStaticClass(
            new Object(), new Object(), new Object()
        );
        myStaticClassInstance.callSomeMethod();
    }
}
我的班级
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();
    }
}
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");
        }
    }
}
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

关于的更多细节。

我编写了一个更简单的工具,用于模拟通常在

您的代码可以如下所示:

``` 公共类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();
}
}


```

是的,很清楚,但不起作用。在执行
新建MyClass.MyStaticClass(arg1、arg2、arg3)时,执行将进入静态类的构造函数内部这是我想要避免的。我没有在定义静态类的公共类中实例化静态类,这与您的代码不同。我将
@PrepareForTest(MyClass.class)
更改为
@PrepareForTest(SomeClass.class)
,它正在工作。谢谢你的代码示例,它对我帮助很大。首先,你不应该在
SomeClass
中实例化
MyStaticClass
。您应该使用依赖项反转将
MyStaticClass
的实例注入
SomeClass