是否可以在现有对象中模拟单个方法? [英] Is it possible to mock a single method in an already existing object?

查看:80
本文介绍了是否可以在现有对象中模拟单个方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于集成测试,我需要在Java服务客户端中模拟特定方法,而又不破坏其中的其余信息。它没有自构造函数,所以这样的解决方案是不可能的:

For an integration test, I need to mock a specific method in a java service client without destroying the rest of the information in it. It has no self-constructor, so a solution like this is out of the question:

private DBClient mockClient = new DBClient(alreadyExistingClient){
    @Override
    void deleteItem(Item i){
        //my stuff goes here
    }
};

是否有一种方法可以模拟deleteItem方法,以便凭据,端点等...保留在现有的DBClient对象中?

Is there a way to mock the deleteItem method such that the credentials, endpoints, etc... are preserved in an existing DBClient object?

编辑:在这种情况下,mockito不可用

edit: mockito is not available for use in this case

推荐答案

您可以使用动态代理来拦截所需的任何方法调用,因此可以决定在调用真实方法还是执行所需的操作之间。

You can use a Dynamic Proxy to intercept any method invocation you want, so you can decide between invoking the real method or do whatever you want instead.

这是一个如何拦截方法 Set.add()的示例,您可以对 deleteItem()进行完全相同的操作

This is an example of how to intercept the method Set.add(), you can do exactly the same for deleteItem()

package example.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Set;

public class SetProxyFactory {

    public static Set<?> getSetProxy(final Set<?> s) {
        final ClassLoader classLoader = s.getClass().getClassLoader();
        final Class<?>[] interfaces = new Class[] {Set.class};
        final InvocationHandler invocationHandler = new InvocationHandler() {

            @Override
            public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {

                if (method.getName().equals("add")) {
                    System.out.println("add() intercepted");
                    // do/return whatever you want
                }

                // or invoke the real method
                return method.invoke(s, args);
            }
        };

        final Object proxy = Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);

        return (Set<?>) proxy;
    }
}

这篇关于是否可以在现有对象中模拟单个方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆