重写泛型类中的方法

发布于 2024-12-07 05:23:33 字数 1824 浏览 1 评论 0原文

我正在重构一些单元测试。基本上,我发现不同客户端的单元测试实现了一系列方法,例如:createClientWithNullResponse、createClientWithSuccessResponse 等。

我想知道是否有可能在 Java 中实现一个通用的解决方案,因为这些方法在数百个单元类,仅更改方法签名。

但是,有一个棘手的问题。看一个方法示例:

/**
 * configures the client to return a succesful response
 * @return a client configured to return a succesful response
 */
private Client1 configureClientWithSuccesfulResponse()
{
    client = new Client1()
    {
        public CommonClientResponse processRequest( CommonsClientRequest commonsClientRequest )
        {
            CommonClientResponse commonClientResponse = new CommonClientResponse();
            commonClientResponse.setResponse( new Client1Response() );
            return commonClientResponse;
        }
    };
    return client;
}

因此,client2 将具有完全相同的方法,只是签名具有 Client2,并且重写的方法创建一个新的 Client2Response,并且与数十个客户端相同。

附加信息:processRequest 被重写以充当模拟,为每个方法设置我希望的响应。 Client1 扩展了 CommonsWS,它扩展了 AbstractCommons,它是一个抽象类,但包含 processRequest 方法的实现。

总而言之,我的想法是为所有单元测试创​​建一个基类,其中包含一组通用方法,我可以在其中传递类类型,然后为每个测试重写 processRequest。我已经尝试过:

public class base <T extends AbstractCommonClient>{

    private T configureClientWithNullResponse(Class <? extends AbstractCommonClient> clazz, Class< ? extends ClientResponse> clazz1)
    {

        try
        {
            return clazz.newInstance()
            {
                CommonClientResponse processRequest( CommonsClientRequest commonsClientRequest )
                {
                    CommonClientResponse commonClientResponse = new CommonClientResponse();
                    commonClientResponse.setResponse( clazz1.newInstance() );
                    return commonClientResponse;
                };
            };
        }
    }

}

但它甚至无法编译。您对我如何开始实施这个有什么想法吗?

Im refactoring some unit tests. Basically, i ve found that unit tests of different clients implement a bundle of methods such as: createClientWithNullResponse, createClientWithSuccessResponse, etc.

I was wondering if its possible in Java to implement a generic solution to this, since this methods are repeated over and over in hundreds of unit classes, changing only the method signature.

But, there is a tricky. See a method example:

/**
 * configures the client to return a succesful response
 * @return a client configured to return a succesful response
 */
private Client1 configureClientWithSuccesfulResponse()
{
    client = new Client1()
    {
        public CommonClientResponse processRequest( CommonsClientRequest commonsClientRequest )
        {
            CommonClientResponse commonClientResponse = new CommonClientResponse();
            commonClientResponse.setResponse( new Client1Response() );
            return commonClientResponse;
        }
    };
    return client;
}

So, client2 will have the very same method except that signature have Client2, and the overrided method creates a new Client2Response, and the same with dozens of clients.

Additional information: processRequest is overrided to act as a mock, setting the response i wish for each method.
Client1 extends CommonsWS that extends of AbstractCommons, which is an abstract class but contains the implementation of processRequest method.

All in all, my idea is to create a Base class for all unit tests, with a bundle of generic methods where i can pass the class type, and then rewrite the processRequest for each one. Ive tried :

public class base <T extends AbstractCommonClient>{

    private T configureClientWithNullResponse(Class <? extends AbstractCommonClient> clazz, Class< ? extends ClientResponse> clazz1)
    {

        try
        {
            return clazz.newInstance()
            {
                CommonClientResponse processRequest( CommonsClientRequest commonsClientRequest )
                {
                    CommonClientResponse commonClientResponse = new CommonClientResponse();
                    commonClientResponse.setResponse( clazz1.newInstance() );
                    return commonClientResponse;
                };
            };
        }
    }

}

but it not even compile. Do you have any ideas of how i can begin implementing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

故事与诗 2024-12-14 05:23:33

当您有效地尝试创建一个在运行时类型未知的匿名类时,您是否考虑过在运行时调用编译器?我自己用得不多,但可能值得研究一下。您可以通过使用调用它。

JavaCompiler compiler = javax.tools.ToolProvider.getSystemJavaCompiler();

注意,只有当应用程序在安装了 JDK 的系统上运行时,这才有效,如 JRE (不包括 javac

As you are effectively trying to create an anonymous class whose type is unknown at runtime, have you considered invoking the compiler at runtime? I haven't used it much myself, but it may be worth investigating. You can invoke it by using

JavaCompiler compiler = javax.tools.ToolProvider.getSystemJavaCompiler();

Note that this will only work if the application is run on a system where JDK is install, as JRE (does not include javac).

愚人国度 2024-12-14 05:23:33

这是一个棘手的问题。我建议创建一个工厂类来返回每种类型的客户端,然后您提供响应并将其传递给工厂。像这样的东西:

public class ClientFactory {

    public static createResponse(ClientResponse response) {
        CommonClientResponse commonClientResponse = new CommonClientResponse();
        commonClientResponse.setResponse(response);
        return commonClientResponse;
    }

    public static Client1 createClient1(final ClientResponse response) {
       return new Client1() {
            public CommonClientResponse processRequest(CommonsClientRequest unused) {
                return createResponse(response)
            };
        }
    };

    public static Client2 createClient2(final ClientResponse response) {
       return new Client2() {
            public CommonClientResponse processRequest(CommonsClientRequest unused) {
                return createResponse(response)
            };
        }
    };

    ..... // same for every type of Client

你可以使用以下方式调用它:

    factory.createClient1(new Client1Response());

仍然有一些重复,但它有帮助。一点。
你怎么认为?

This is a tricky question. I suggest create a Factory class that would return each type of client, and you provide the response and pass it to the factory. Something like:

public class ClientFactory {

    public static createResponse(ClientResponse response) {
        CommonClientResponse commonClientResponse = new CommonClientResponse();
        commonClientResponse.setResponse(response);
        return commonClientResponse;
    }

    public static Client1 createClient1(final ClientResponse response) {
       return new Client1() {
            public CommonClientResponse processRequest(CommonsClientRequest unused) {
                return createResponse(response)
            };
        }
    };

    public static Client2 createClient2(final ClientResponse response) {
       return new Client2() {
            public CommonClientResponse processRequest(CommonsClientRequest unused) {
                return createResponse(response)
            };
        }
    };

    ..... // same for every type of Client

And you call it using:

    factory.createClient1(new Client1Response());

There is still some duplication, but it helps. A little.
What do you think?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文