Junit 外部资源 @Rule 顺序

7

我想在我的测试类中使用多个外部资源,但是我在外部资源的排序方面遇到了问题。

这里是代码片段:

public class TestPigExternalResource {

     // hadoop external resource, this should start first
     @Rule
     public HadoopSingleNodeCluster cluster = new HadoopSingleNodeCluster();

     // pig external resourcem, this should wait until hadoop external resource starts
     @Rule
     public  PigExternalResource pigExternalResource = new PigExternalResource(); 

     ...  
}

问题在于它试图在hadoop启动之前启动pig,因此我无法连接本地hadoop单节点集群。
有没有办法对junit的规则进行排序?
谢谢

HadoopSingleNodeCluster类是否公开可用?因为我使用org.apache.hadoop.mapred.ClusterMapReduceTestCase,但它不是很稳定。 - nefo_x
@nefo_x HadoopSingleNodeCluster 是我自己的类,不在 Hadoop 分发中提供。 - Salih Kardan
这是基于某个现有代码库吗?我尝试使用集群MapReduce测试用例,但它会启动外部JVM,这在某些情况下对调试有点困难。 - nefo_x
3个回答

11

您可以使用RuleChain

@Rule
public TestRule chain= RuleChain.outerRule(new HadoopSingleNodeCluster())
                           .around(new PigExternalResource());

1

JUnit 4.13-beta-1中的@Rule@ClassRule新增了一个名为order的属性。

请参见@Rule代码:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface Rule {

    int DEFAULT_ORDER = -1;

    /**
     * Specifies the order in which rules are applied. The rules with a higher value are inner.
     *
     * @since 4.13
     */
    int order() default DEFAULT_ORDER;

}

请参考此 PR:PR-1445

1
为什么不将这两个ExternalResources包装在您自己的ExternalResource中,在新资源的beforeafter方法中按照您所需的顺序调用beforeafter方法。
示例:
public class MyResource extends ExternalResource{
     private final List<ExternalResource> beforeResources;
     private final List<ExternalResource> afterResources;

     public MyResource(List<ExternalResource> beforeResources,
          List<ExternalResource> beforeResources){
     }

      public void before(){
          for (ExternalResource er : beforeResources)
               er.before();
      }

      public void after(){
          for (ExternalResource er : afterResources)
               er.after();
      }
}


public class TestPigExternalResource {

 // hadoop external resource, this should start first
 public HadoopSingleNodeCluster cluster = new HadoopSingleNodeCluster();

 // pig external resourcem, this should wait until hadoop external resource starts
 public  PigExternalResource pigExternalResource = new PigExternalResource(); 

  @Rule
  public MyResource myResource = new MyResource(
          newArrayList(cluster, pigExternalResource),
          newArrayList(cluster, pigExternalResource));
 ...  
}

谢谢,但我猜在@Before和@After方法中使用@Rule注释是不允许的。 - Salih Kardan
由于它们将被包含在封装规则中,因此其他资源将不再被标记为规则。 - John B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接