有一种优雅的方法可以克服TestNG的依赖注入缺点吗?

时间:2015-06-04 18:36:16

标签: java testng

根据我的经验,TestNG是最灵活的测试Java框架。但是,它确实存在一些不一致之处。我遇到的主要问题是缺乏对侦听器和方法选择器中依赖注入的支持。在编写位于TestNG之上的可重用测试工具时,此功能至关重要。我只能提出两个解决方法的想法(第一个是黑客,第二个是痛苦),所以我想知道是否有人能想出更好的方法。

首先,hacky方式

创建表示单身的枚举

package com.example;
//other imports

public enum Injection {
  INJECTION

  private Injector guiceInjector;

  public void setGuiceInjector(final Injector guiceInjector) {
    this.guiceInjector = guiceInjector;
  }

  public void injectInto(final Object obj) {
    Objects.requireNonNull(this.guiceInjector).injectMembers(obj);
  }
}

按如下方式实施org.testng.IObjectFactory2

package com.example;

import static com.example.Injection.INJECTION;
//other imports

public final class GuiceBootstrap implements IObjectFactory2 {
  private final Injector injector;

  public GuiceBootstrap() {
    this.injector = Guice.createInjector(/*modules*/);
    INJECTION.setGuiceInjector(this.injector);
  }

  @Override
  public Object newInstance(final Class<?> kind) {
    return injector.getInstance(kind);
  }
}

根据需要使用枚举injectInto,例如:

package com.example;

import static com.example.Injection.INJECTION;
//other imports

public final class SimpleRetryAnalyzer implements IRetryAnalyzer {
  @Inject @MaxRetryCount private int maxRetries;
  private int retriesSoFar;

  public SimpleRetryAnalyzer() {
    INJECTION.injectInto(this);
    retriesSoFar = 0;
  }

  public boolean retry(final ITestResult result) {
    //implementation
  }
}

我总体上鄙视可变状态,所以我并不认为这是一种有效的方法。此外,没有什么可以阻止利用这种方法的测试工具的用户直接访问枚举(即使它的意味着是内部的)。哈克,不洁,涉及可变状态......

第二,痛苦的方式

远离TestNG,并以编程方式使用它:

package com.example;

public CustomTestNgLauncher {
  public static void main(String... args) {
    final Injector injector = Guice.createInjector(determineGuiceModules(args));
    final ITestObjectFactory guiceObjectFactory = createGuiceObjectFactory(injector);
    final TestNG testNg = new TestNG();
    testNg.setObjectFactory(guiceObjectFactory);
    testNg.setOutputDirectory(reportsDirPathOrNull);
    testNg.setTestSuites(determineTestNgSuites());
    testNg.addListener(injector.getInstance(SomeCustomListener.class));
  }
}

在我看来,这是对第一种方法的改进,但是注入方法选择器的问题仍然存在,因为TestNG#addMethodSelector接受String而不是接受{{3}的实例} ...

0 个答案:

没有答案