我有一些像这样的Java东西:
public interface EventBus{
void fireEvent(GwtEvent<?> event);
}
public class SaveCommentEvent extends GwtEvent<?>{
private finalComment oldComment;
private final Comment newComment;
public SaveCommentEvent(Comment oldComment,Comment newComment){
this.oldComment=oldComment;
this.newComment=newComment;
}
public Comment getOldComment(){...}
public Comment getNewComment(){...}
}
并测试代码如下:
def "...."(){
EventBus eventBus=Mock()
Comment oldComment=Mock()
Comment newCommnet=Mock()
when:
eventBus.fireEvent(new SaveCommentEvent(oldComment,newComment))
then:
1*eventBus.fireEvent(
{
it.source.getClass()==SaveCommentEvent;
it.oldComment==oldComment;
it.newComment==newComment
}
)
}
我想验证eventBus.fireEvent(..)
是否会在类型为SaveCommentEvent
且构造参数oldComment
和newComment
的事件中被调用一次。
代码运行没有错误,但问题是:
从
更改封面内容后{
it.source.getClass()==SaveCommentEvent;
it.oldComment==oldComment; //old==old
it.newComment==newComment //new==new
}
到
{
it.source.getClass()==Other_Class_Literal;
it.oldComment==newComment; //old==new
it.newComment==oldComment //new==old
}
仍然,代码运行没有错误?显然关闭没有做我想要的,所以问题是:如何进行参数捕获?
答案 0 :(得分:33)
我明白了:
SaveCommentEvent firedEvent
given:
...
when:
....
then:
1 * eventBus.fireEvent(_) >> {arguments -> firedEvent=arguments[0]}
firedEvent instanceof SaveModelEvent
firedEvent.newModel == newModel
firedEvent.oldModel == oldModel
答案 1 :(得分:4)
then:
1*eventBus.fireEvent(
{
it.source.getClass()==SaveCommentEvent;
it.oldComment==oldComment;
it.newComment==newComment
}
)
在您的代码中it
是对模拟eventBus接口的Groovy Closure Implicit Variable引用,该接口没有字段。你怎么验证他们?
另外,我认为使用Spock Mocks必须发生的事件顺序不一定直观。我会在这里写下来,除非它不如Kenneth Kousen's explanation那么好。
答案 2 :(得分:0)
在上面@ alex-luya的回答中,我发现变量firedEvent
需要@Shared
注释。
然后,我可以捕获值并在闭包之外对值进行检查。
答案 3 :(得分:0)
如果您在explicit interaction block中的方法中捕获参数,则该参数在交互闭包的外部 可用,但在闭包的 inside 中不可用。
例如:
SaveCommentEvent firedEvent = null
void captureFiredEvent(EventBus eventBus) {
1 * eventBus.fireEvent(_) >> {arguments -> firedEvent=arguments[0]}
// firedEvent *cannot* be checked here. The following line will fail:
// firedEvent instanceof SaveModelEvent
}
void "test eventBus"() {
given:
...
when:
....
then:
interaction { captureFiredEvent(eventBus) }
// firedEvent can be checked here
firedEvent instanceof SaveModelEvent
}
答案 4 :(得分:0)
与@Alex Luya的想法相同,但是将这些断言放在结尾并在每个断言上使用assert
。 cf. Spock Framework Reference Documentation。
then:
1 * eventBus.fireEvent(_) >> {
def firedEvent = it[0]
assert firedEvent instanceof SaveModelEvent
assert firedEvent.newModel == newModel
assert firedEvent.oldModel == oldModel
}
答案 5 :(得分:0)
在 2021 年(7 年后),可以使用 groovy (2.5) 执行以下操作:
...
then:
1 * eventBus.fireEvent(_) >> { SaveModelEvent event ->
event.newModel == newModel
event.oldModel == oldModel
}
0 * _
...这对我来说感觉更方便并且节省了一两行。 :)