2014-03-06 27 views
20

我在Groovy单元测试中很难理解有关Spock交互的内容。Spock:可以在测试用例中替换setup()中定义的交互吗?

我有以下几种类型:

public interface Bar { 
    public String getMessage(); 
} 

public class Foo { 
    private Bar bar; 
    public void setBar(Bar bar) { 
    this.bar = bar; 
    } 
    public String getMessage() { 
    return bar.getMessage(); 
    } 
} 

,然后我写了下面的Groovy /斯波克测试:

class FooSpec extends Specification { 

    private Bar bar; 
    private Foo foo; 

    def setup() { 
    bar = Mock(Bar) { getMessage() >> "hello" } 
    foo = new Foo() 
    foo.bar = bar 
    } 

    def "say hello"() { 
    expect: 
    foo.message.equals("hello") 
    } 

    def "say goodbye"() { 
    setup: 
    bar.getMessage() >> "goodbye" 

    expect: 
    foo.message.equals("goodbye") 
    } 
} 

的代码创建在设置一个模拟Bar实例初始化Bar.getMessage()返回hello,并将其分配给新的Foo实例。

第一个测试验证foo.getMessage()等于hello

第二个测试试图修改bar模拟,以便它的getMessage方法返回goodbye。然后我们预计foo.getMessage()(代表bar.getMessage())将返回goodbye。然而,测试如下失败:

FooSpec:说再见:26条件不满足

因为foo.message仍然等于hello

我也试过如下:

def "say goodbye"() { 
    when: 
    bar.getMessage() >> "goodbye" 

    then: 
    foo.message.equals("goodbye") 
} 

和:

def "say goodbye"() { 
    when: 
    no_op() 

    then: 
    bar.getMessage() >> "goodbye" 
    foo.message.equals("goodbye") 
} 

但都无法与同招呼不等于告别消息。

我可能还在考虑在模式的Mockito,并假定的相互作用是when(...).thenReturn(...)表达的等价物,而后来的相互作用会覆盖前面的相互作用。

是否有一种使用Spock在setup方法中声明交互的简单方法,然后在测试用例中覆盖该交互?或者我需要删除setup()方法,并基本上添加一个setup:块到每个测试用例?

回答

19

这是一个棘手的问题。如docs中所述,在then-block中声明的交互优先于早先声明的交互。然而,在then块中声明的交互作用范围是前一个when块。 (这允许有多个时,则对)。因此您的最后一次尝试不起作用,但下面的意志:

def setup() { 
    bar.message >> "hello" 
} 

def "say goodbye"() { 
    when: 
    def msg = foo.message 

    then: 
    bar.message >> "goodbye" 
    msg == "goodbye" 
} 

我同意,这将是很好的测试方法始终覆盖相互作用宣布相互作用在设置方法中声明。无论如何,覆盖交互的一个很好的选择是每个测试方法调用一个帮助方法,为该测试方法设置预期的交互。

+0

感谢您的评论。我将避免使用'setup()'方法并改变我的测试方法以直接初始化它们的状态(这也是因为我经常在我的测试方法中使用'where:'块,并发现我惊讶的是'setup()'方法是在'where:'块之后调用的)。我认为*我可以理解你的上面的例子,但它不直观(它仍然看起来像'then:'块中的设置代码给我)。 –

+0

@PeterNiederwieser,你在这个例子中使用了什么Spock版本?我们已经尝试了这个以及Spock 1.0中的很多其他变体,但它没有奏效。 – falsarella

相关问题