Java 如何使JBehave与期望驱动的API一起很好地工作?

Java 如何使JBehave与期望驱动的API一起很好地工作?,java,bdd,jbehave,Java,Bdd,Jbehave,编写BDD场景的常规方法是: Given [some preconditions] When [My code runs] Then [some stuff happened] 但我使用的是一个类似模拟的API,它希望在运行测试代码之前定义期望(即“发生了一些事情”)。为了支持该API,我必须这样写我的故事: Given [some preconditions] And [the expectation that some stuff is going to happen] When [

编写BDD场景的常规方法是:

 Given [some preconditions]
 When [My code runs]
 Then [some stuff happened]
但我使用的是一个类似模拟的API,它希望在运行测试代码之前定义期望(即“发生了一些事情”)。为了支持该API,我必须这样写我的故事:

Given [some preconditions]
And [the expectation that some stuff is going to happen]
When [My code runs]
Then [the expectations I defined above were met]
我不想那样做。我可以看到两种笨拙的方法,我也不想这样做:

  • 在某些“给定”步骤中隐式设置“any”类型期望,使用模拟API的“capture”功能将调用隐藏到字段中,并在“Then”步骤中检查这些调用
  • 。。。或者让“When”步骤设置一个字段,告诉一个AfterScenario步骤运行我的代码,从而将其推迟到期望值设置之后(但阻止我检查其他后置条件)
我真正想要的是JBehave查看Then步骤,找到其中设置期望的部分,并在When之前运行这些步骤

Spock通过模拟实现了这一点(注释显示执行顺序):

def translator=Mock(translator)
无效“测试某事”{
鉴于:
testObj=newmything(translator)//1
什么时候:
def actual=testObj.run(“foo”)//3
然后:

1*translator.process(“foo”)奇怪的是,JBehave 1.0,第一个BDD工具,过去有自己的模拟框架,过去的行为方式与Spock相同。这很讨厌。真的,真的很讨厌(从BDD的角度来看;从“严格的模拟”测试的角度来看,这很好)

该模式是当时任何模拟框架工作的唯一方式,并导致了Mockito和其他“不错的”模拟框架的发明(并且从JBehave 2.0中删除了前面提到的模拟框架,因为它不再需要)

因此,如果Mockito不能为您完成任务,那么“整洁模式”是编写您自己的模拟框架。不那么整洁的模式是编写您自己的BDD框架。在我看来,拥有一个符合实际情况的模拟框架通常更简单


或者,您可能会发现您正在使用的模拟框架有一个“不错”的模式,或者允许您声明存根而不是模拟,这可能会有所帮助。如果不知道您正在使用哪个框架,就很难说清楚。

谢谢。“类似模拟”的模式我使用的框架实际上是一个模拟REST服务;REST客户机驱动程序,在其中,您可以告诉嵌入式Jetty HTTP请求的预期内容,因此我无法切换到Mockito。@slim那里没有大量的代码。我打赌您可以在几天内完成它并编写适合您所做的内容。
def translator = Mock(Translator)

void "test something" {
    given: 
      testObj = new MyThing(translator)  // 1
    when:
      def actual = testObj.run("foo")   // 3
    then:
      1 * translator.process("foo") << "bar" // 2 (setup) 
                                             // and 4 (post-check)
      actual == "bar"  // 5
}