簡體   English   中英

有沒有辦法將 groovy 閉包作為變量注入 Spock 模擬謂詞參數

[英]Is there a way to inject a groovy closure as variable into Spock mock predicate argument

我在 Spock 交互文檔中發現了一行有趣的內容:

http://spockframework.org/spock/docs/1.3/interaction_based_testing.html#_argument_constraints

最后一行約束,帶有閉包謂詞的示例:

1 * subscriber.receive({ it.size() > 3 && it.contains('a') })

我的問題是: Groovy 中有沒有辦法將此謂詞作為變量傳遞?

我的測試環境代碼:

class Something {
   Doer doer

   Something(Doer doer) {
      this.doer = doer
   }

   boolean doSth(x) {
      if (!doer.validate(x)) throw new RuntimeException()
      true
   }
}

class Doer {
   boolean validate(int x) {
      x == 2
   }
}

和測試代碼:

   def "some test"() {
      given:
      def d = Mock(Doer)
      def s = new Something(d)

      when:
      s.doSth(2)

      then:
      1 * d.validate({ it == 2 }) >> true
   }

我想實現的目標:

def "some test"() {
      given:
      def d = Mock(Doer)
      def s = new Something(d)
      def myClosureVar = { ??? }

      when:
      s.doSth(2)

      then:
      1 * d.validate(myClosureVar) >> true
   }

閉包接受一個參數,正如it具有定義的值所指示的那樣。 該值是相應的方法參數。 因此,無論您在交互之外定義什么閉包,您都需要確保交互將該參數傳遞給閉包,即您需要創建自己的(小而簡單的)閉包來評估外部(可能更長、更復雜)的閉包使用參數it

1 * d.validate({ myClosureVar(it) }) >> true

抱歉重復,但我總是更喜歡在我的答案中使用完整的MCVE ,以便您可以輕松復制、粘貼、編譯和運行:

應用類:

package de.scrum_master.stackoverflow.q60341734

class Doer {
  boolean validate(int x) {
    x == 2
  }
}
package de.scrum_master.stackoverflow.q60341734

class Something {
  Doer doer

  Something(Doer doer) {
    this.doer = doer
  }

  boolean doSth(x) {
    if (!doer.validate(x)) throw new RuntimeException()
    true
  }
}

斯波克規格:

package de.scrum_master.stackoverflow.q60341734

import org.junit.Rule
import org.junit.rules.TestName
import spock.lang.Specification

class SomethingTest extends Specification {
  @Rule
  TestName testName

  def "some test"() {
    given:
    def d = Mock(Doer)
    def s = new Something(d)

    when:
    s.doSth(2)

    then:
    1 * d.validate({ println "$testName.methodName: closure parameter = $it"; it == 2 }) >> true
  }

  def "another test"() {
    given:
    def d = Mock(Doer)
    def s = new Something(d)
    def myClosureVar = { println "$testName.methodName: closure parameter = $it"; it == 2 }

    when:
    s.doSth(2)

    then:
    1 * d.validate({ myClosureVar(it) }) >> true
  }
}

控制台日志:

some test: closure parameter = 2
another test: closure parameter = 2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM