什么时候Spock的@Shared注释比静态字段更受欢迎?

top*_*opr 17 groovy unit-testing spock

没有太多补充,整个问题在标题中.

考虑Spock规范中使用的这两个Foo类实例.

@Shared Foo foo1 = new Foo()

static Foo foo2 = new Foo()
Run Code Online (Sandbox Code Playgroud)

总的来说,我知道@Shared注释背后的想法,但我想最好使用语言功能,在这种情况下将是static字段.

是否有任何特定的案例,其中一个人应该优先于另一个,或者它是一个品味问题?

kaz*_*aki 13

Spock是关于表现力清晰度的.

Static是一个Java关键字,仅显示类的内部(该字段对于所有实例都是相同的)

@Shared是一个Spock功能,它告诉读者这个变量对于所有特征方法都是相同的.它是专门针对单元测试的指令,使读者可以更清楚地进行单元测试.

主Spock块也是如此.如果你考虑一下,他们并没有真正改变代码.

public void myScenario(){
  int a = 2 + 3;
  assertEquals(5,a);
}

public void "simple addition scenario"(){
  when: "I add two numbers"
    int a = 2 +3

  then: "I expect the correct result"
  a == 5
}
Run Code Online (Sandbox Code Playgroud)

两个单元测试在技术上完全相同.然而,第二个更清楚地表明了意图.的时候:则:标签不确实比澄清其意图之外的任何代码.

总而言之,@ Shared使测试更具可读性.(另见@Issue,@标题等,它们的出现也是出于同一目的)


Val*_*lya 9

与JUnit相反,您必须在其中声明字段变量static并为其赋值

@BeforeClass
public static void setupClass()
Run Code Online (Sandbox Code Playgroud)

所以每个测试套件(不是每个方法)只初始化一次,在Spock中你可以使用实例字段变量并用它注释@Shared.

请考虑以下示例:

class SharedTestSpec extends spock.lang.Specification {

    @Shared
    def shared = shared()

    def shared() {
        "I came from ${this.class.simpleName}"
    }

    def 'Test one'() {
        given:
            println("test one, shared: $shared")
        expect: true
    }

    def 'Test two'() {
        given:
            println("test two, shared: $shared")
        expect: true

    }
}

class SubclassSpec extends SharedTestSpec {

    @Override
    def shared() {
        println("They've got me!")
        "I came from ${this.class.simpleName}"
    }
}
Run Code Online (Sandbox Code Playgroud)

运行SubclassSpec会为您提供以下输出:

test one, shared: I came from SubclassSpec
test two, shared: I came from SubclassSpec
They've got me!
Run Code Online (Sandbox Code Playgroud)

虽然无法解释打印顺序,但这是由于AST.