如何在ExtensionContext.Store中存储可变对象

问题描述

在大多数情况下,当我考虑创建扩展时,都会遇到相同的问题:如何存储可变对象?这是我的问题:让我们考虑一下,我的扩展程序提供了一个 parameter resolver ,它为测试提供了可变的对象。假设该对象具有更改配置的方法。基于JUnit 5 User GuideJavadoc的天真的实现可能看起来像这样:

public class MyExtension implements ParameterResolver {
  private static final Namespace NAMESPACE = Namespace.create(MyExtension.class);

  public boolean supportsParameter(ParameterContext parameterContext,ExtensionContext extensionContext) {
    return parameterContext.getParameter().getType() == MyMutableType.class;
  }

  public Object resolveParameter(ParameterContext parameterContext,ExtensionContext extensionContext) {
    return extensionContext.getStore(NAMESPACE).getorComputeIfAbsent(MyMutableType.class,__ -> new MyMutableType());
  }
}

不幸的是,以下测试类的实现已被破坏。

@ExtendWith(MyExtension.class)
final class MyTest {
  @BeforeAll
  static void init(MyMutableType resolvedobject) {
  }

  @Test
  void test1(MyMutableType resolvedobject) {
    resolvedobject.changeSomeConfig();
    ...
  }

  @Test
  void test2(MyMutableType resolvedobject) {
    // resolvedobject might be affected by changed configuration in test1().
    ...
  }
}

直到今天,我都找不到一个好的解决方案。 JUnit是否提供了有关该如何工作的指南。我什么都找不到。为了解决这个问题,我看到了两种方法。它们似乎都无法与JUnit的API很好地配合。

一种方法是在ExtensionContext不是特定于单个测试时禁止使用我的参数解析器。不幸的是,我找不到任何可靠的方法来进行检查。我可以检查@BeforeAll之类的注释,但这更多的是估算,而不是可靠的检查。

第二种方法是在输入更具体的ExtensionContext时复制对象。另外,我可以设置一个标志,以防止进一步修改并提供有意义的错误消息。但是,这种实现远非简单易懂,而更像是滥用API。除此之外,当实际不需要时,通过使用copyOperator可能会过于严格。

<T> T getorCompute(ExtensionContext extensionContext,Object key,supplier<T> factory,UnaryOperator<T> copyOperator) {
  Store store = extensionContext.getStore(NAMESPACE);
  // Using remove() because it is the only method ignoring ancestors
  Object prevIoUs = store.remove(key);
  if (prevIoUs == null) {
    T fromAncestor = (T) store.get(key);
    if (fromAncestor == null) {
      T result = factory.get();
      store.put(key,result);
      return result;
    }
    else {
      T result = copyOperator.apply(fromAncestor);
      store.put(key,result);
      return result;
    }
  }
  else {
    store.put(key,prevIoUs);
    return (T) prevIoUs;
  }
}

我想知道我是否缺少重要的东西,或者JUnit是否没有有意义的方式来处理扩展中的可变状态。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)