JUnit5. 如何在两个参数解析器之间共享实例?

huangapple go评论70阅读模式
英文:

JUnit5. How to share instance between to parameter resolvers?

问题

我有一个 ParameterResolver。它返回一个 MyHttpClient 实例。它有效。没问题。

public class HttpClientProvider implements ParameterResolver {
    @Override
    public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
        return parameterContext.getParameter().getType().equals(MyHttpClient.class);
    }

    @Override
    public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
        return new MyHttpClient();
    }
}

我想创建另一个 ParameterResolver。它应该返回一个由 Http 请求创建的实体。因此,要发出请求,我需要提供一个客户端。目前它只是一个私有字段。

public class EntityProvider implements ParameterResolver {
    private final MyHttpClient client = new MyHttpClient();

    @Override
    public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
        return parameterContext.getParameter().getType().equals(MyEntity.class);
    }

    @Override
    public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
        MyEntity item = client.create();
        return item;
    }
}

问题

问题是我必须为 HttpClientProviderEntityProvider 分别创建 MyHttpClient 两次(为了创建请求)。这是代码重复。

问题:

有没有办法从 EntityProvider 调用 HttpClientProvider:resolveParameter 或者 某种方式 在两个 ParameterResolver 之间共享一个 MyHttpClient 的实例?

更新 解决复制粘贴的问题

感谢 @johanneslink 的解决方案,可以使用存储来解决。

如何共享(HttpClientProvider)

public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
        MyHttpClient client = new MyHttpClient();
        extensionContext.getStore(Namespace.GLOBAL).put("client", client);
        return client;
    }

如何获取(EntityProvider)

public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
        MyHttpClient client = (MyHttpClient)extensionContext.getStore(Namespace.GLOBAL).get("client");
        MyEntity item = client.create();
        return item;
    }
英文:

Hi

I have a ParameterResolver. It returns a MyHttpClient instance. It works. It's ok.

public class HttpClientProvider implements ParameterResolver {
    @Override
    public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
        return parameterContext.getParameter().getType().equals(MyHttpClient.class);
    }

    @Override
    public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
        return new MyHttpClient();
    }
}

I want to create another one ParameterResolver. It should return an entity created by Http request. So to make a request, I need to provide a client. For now it's just a private field.

public class EntityProvider implements ParameterResolver {
    private final MyHttpClient client = new MyHttpClient();

    @Override
    public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
        return parameterContext.getParameter().getType().equals(MyEntity.class);
    }

    @Override
    public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
            MyEntity item = client.create();
            return item;
    }

The problem is

I have to create MyHttpClient twice: for HttpClientProvider and in EntityProvider (to make a create-request). This is code duplication.

Question:

Is there any solution to call HttpClientProvider:resolveParameter from EntityProvider or somehow share one instance of MyHttpClient between two ParameterResolver's?

UPD. Solution for copy-pasting

Thanks to @johanneslink solution is using Storages.

How to share (HttpClientProvider)

public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
        MyHttpClient client = new MyHttpClient();
        extensionContext.getStore(Namespace.GLOBAL).put("client", client);
        return client;
    }

Ho to get (EntityProvider)

    public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
        MyHttpClient client = (MyHttpClient)extensionContext.getStore(Namespace.GLOBAL).get("client");
        MyEntity item = client.create();
        return item;
    }

答案1

得分: 0

保持扩展中的状态是通过 Jupiter 称之为 "stores" 来实现的。
已记录在这里

另一个 StackOverflow 回答描述了这种方法:https://stackoverflow.com/a/53142365/32352

永远不要使用扩展中的成员变量并假设同一扩展的下一次调用会给你相同的值。扩展实例的生命周期大部分情况下是未定义的(故意如此),因为它取决于上下文。测试的顺序、并发测试执行和测试类的嵌套都会影响这里的情况。

英文:

Keeping state in extensions is done through what Jupiter calls "stores".
It's documented here.

Another StackOverflow answers that describes the approach: https://stackoverflow.com/a/53142365/32352

What you should never do is use member variables in extensions and assume that the next invocation of the same extension will give you the same value back. The lifecycle of extension instances is mostly (and on purpose) undefined because it is context-dependent. Order of tests, concurrent test execution and nesting of test classes all play a role here.

huangapple
  • 本文由 发表于 2023年7月13日 21:23:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/76679865.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定