Java 创建没有框架的模拟对象

Java 创建没有框架的模拟对象,java,mocking,Java,Mocking,我目前正在使用EasyMock并创建类似这样的模拟对象 mockedObject = createMock(myInterface.class); Easy mock是一个不必要的开销(因为我模拟的方法非常简单),我希望创建一个没有它的模拟 但问题是myInterface是一个接口,所以我如何实例化它。请建议 谢谢, Sriram您不能实例化接口,您需要使用它的一个实现。既然您已经决定放弃EasyMock(不知道为什么),那么您需要实例化一个现有的接口实现,或者创建一个新的接口来进行测试。您无

我目前正在使用EasyMock并创建类似这样的模拟对象

mockedObject = createMock(myInterface.class);
Easy mock是一个不必要的开销(因为我模拟的方法非常简单),我希望创建一个没有它的模拟

但问题是myInterface是一个接口,所以我如何实例化它。请建议

谢谢,
Sriram

您不能实例化接口,您需要使用它的一个实现。既然您已经决定放弃EasyMock(不知道为什么),那么您需要实例化一个现有的接口实现,或者创建一个新的接口来进行测试。

您无法实例化接口,您需要使用它的一个实现。既然您已经决定放弃EasyMock(不知道为什么),那么您需要实例化一个现有的接口实现,或者创建一个新的接口实现以进行测试。

最简单的方法是创建一个实现接口的内部类,实现返回所需数据的方法,然后在测试用例中使用它

例如:

public void testMethod ( )
{
    MyInterface mockObject = new MyInterface ( ) {
        public void myMethod ( )
        {
            // NOOP
        }

        public int myFunction ( )
        {
            return -1 ;
        }
    }

    // Proceed with the test case using mockObject
}

最简单的方法是创建一个实现接口的内部类,实现返回所需数据的方法,然后在测试用例中使用它

例如:

public void testMethod ( )
{
    MyInterface mockObject = new MyInterface ( ) {
        public void myMethod ( )
        {
            // NOOP
        }

        public int myFunction ( )
        {
            return -1 ;
        }
    }

    // Proceed with the test case using mockObject
}

你可以创建一个新的类

   MyInterface myMock = new MyInterface() {
                               ... methods implemented here
                            };

你可以创建一个新的类

   MyInterface myMock = new MyInterface() {
                               ... methods implemented here
                            };

如果需要验证方法的调用次数,可以为每个方法添加一个简单的计数器成员

e、 g


如果需要验证方法的调用次数,可以为每个方法添加一个简单的计数器成员

e、 g


如果没有模拟框架,java.lang.reflect.Proxy是最好的选择。如果您以前从未使用过它,那么可以创建一个实现一组接口的动态对象,并使用InvocationHandler检查每个方法调用并决定要做什么。这是一种非常强大的技术(不限于测试),因为您可以将方法调用委托给其他对象,等等。。。。当您执行这种委托时,它还将您与某些接口更改隔离开来,因为您没有声明每个方法。它适应runtine的接口

public static interface MyIntf {
  String foo(String arg1);
}

InvocationHandler invocationHandler = new InvocationHandler() {
   @Override
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       if (method.getName().equals("foo") && 
           method.getParameterTypes().length == 1 &&
           method.getParameterTypes()[0] == String.class) {
           // do your mocking here.  For now i'll just return the input
           return args[0];
       }
       else {
           return null;
       }
   }
};

MyIntf myintf = (MyIntf) Proxy.newProxyInstance(getClass().getClassLoader(),
            new Class[] { MyIntf.class },
            invocationHandler);

System.out.println(myintf.foo("abc"));

如果没有模拟框架,java.lang.reflect.Proxy是最好的选择。如果您以前从未使用过它,那么可以创建一个实现一组接口的动态对象,并使用InvocationHandler检查每个方法调用并决定要做什么。这是一种非常强大的技术(不限于测试),因为您可以将方法调用委托给其他对象,等等。。。。当您执行这种委托时,它还将您与某些接口更改隔离开来,因为您没有声明每个方法。它适应runtine的接口

public static interface MyIntf {
  String foo(String arg1);
}

InvocationHandler invocationHandler = new InvocationHandler() {
   @Override
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       if (method.getName().equals("foo") && 
           method.getParameterTypes().length == 1 &&
           method.getParameterTypes()[0] == String.class) {
           // do your mocking here.  For now i'll just return the input
           return args[0];
       }
       else {
           return null;
       }
   }
};

MyIntf myintf = (MyIntf) Proxy.newProxyInstance(getClass().getClassLoader(),
            new Class[] { MyIntf.class },
            invocationHandler);

System.out.println(myintf.foo("abc"));

这取决于您是否会再次重用该类的特定实现。在我的例子中,许多模拟对象都是以匿名内部类的形式开始的,当我开始重用它们时,它们发现自己被提升到了完全充实的类。@sriram仅供记录。大多数显式创建的模拟对象最终会消失,并被EasyMock取代。一旦模拟对象达到一定的复杂程度,维护它就比简单地使用EasyMock要困难得多。@Hagger是的,我知道,但在这种情况下,我对模拟的使用非常有限,因此不需要额外的开销。我只需要模拟一个函数,这取决于您是否会再次重用该类的特定实现。在我的例子中,许多模拟对象都是以匿名内部类的形式开始的,当我开始重用它们时,它们发现自己被提升到了完全充实的类。@sriram仅供记录。大多数显式创建的模拟对象最终会消失,并被EasyMock取代。一旦模拟对象达到一定的复杂程度,维护它就比简单地使用EasyMock要困难得多。@Hagger是的,我知道,但在这种情况下,我对模拟的使用非常有限,因此不需要额外的开销。我只有一个要模拟的函数。这个模式很棒。这个模式很棒