【问题标题】:How to reuse feature methods in a @Stepwise Spock specification?如何在@Stepwise Spock 规范中重用特征方法?
【发布时间】:2014-08-25 07:27:53
【问题描述】:

我有两个 Spock 规范,都从不同的起点测试了一个很长的过程,所以就像

@Stepwise
class FooSpec extends Specification {
    def "setup1"() {...}
    def "setup2"() {...}
    def "common1"() {...}
    def "common2"() {...}
    ...
}

@Stepwise
class BarSpec extends Specification {
    def "setup3"() {...}
    def "setup4"() {...}
    def "common1"() {...}
    def "common2"() {...}
    ...
}

现在我想重构我的代码以删除所有常见* 功能方法的重复数据,这些方法将在不同的设置之后执行。

我尝试使用子类化,但超类的功能方法在之前执行,而不是在子类的功能方法之后。我还尝试编写自己的 Spock 扩展(Groovy 2 的 Spock 版本 0.7),但找不到在那里实现我想要的行为的方法。

【问题讨论】:

    标签: groovy spock


    【解决方案1】:

    查阅StepwiseExtension的源码,终于想出了自己的解决方案:

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @ExtensionAnnotation(BeforeSuperExtension)
    @interface BeforeSuper {}
    

    此注释标记@Stepwise 测试中的特征方法,应在super 的特征方法之前执行。

    扩展实现会相应地重新排列执行顺序:

    class BeforeSuperExtension extends AbstractAnnotationDrivenExtension<BeforeSuper>
    {
        def beforeSuper = []
    
        @Override
        void visitFeatureAnnotation(BeforeSuper annotation, FeatureInfo feature)
        {
            beforeSuper << feature
        }
    
        @Override
        void visitSpec(SpecInfo spec)
        {
            def superFeatures = spec.superSpec.allFeaturesInExecutionOrder
            def afterSuper = spec.features - beforeSuper
    
            (beforeSuper + superFeatures + afterSuper).eachWithIndex { f, i ->
                f.executionOrder = i
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      common* 方法放在基类中,并使用setupSpec() 方法(而不是setup* 方法)添加两个子类。

      【讨论】:

      • 设置非常复杂,可以拆分为多个特征方法。我想保留这种粒度。
      【解决方案3】:

      我实现了相反的策略,使用注释@AfterSubSpec 告诉超类中的常用方法在子类中的方法之后运行:

      class AfterSubSpecExtension extends AbstractAnnotationDrivenExtension<AfterSubSpec> {
      
          def afterSub = []
      
          @Override
          void visitFeatureAnnotation(AfterSubSpec annotation, FeatureInfo feature) {
              afterSub << feature
          }
      
          @Override
          void visitSpec(SpecInfo spec) {
              def subSpecFeatures = spec.bottomSpec.allFeaturesInExecutionOrder - afterSub
      
              (subSpecFeatures + afterSub).eachWithIndex { f, i -> f.executionOrder = i }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-08-20
        • 1970-01-01
        • 2020-07-20
        • 2016-04-14
        • 2015-08-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多