Как сделать захват аргументов с помощью фреймворка spock?
У меня есть 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
}
To
{
it.source.getClass()==Other_Class_Literal;
it.oldComment==newComment; //old==new
it.newComment==oldComment //new==old
}
Тем не менее, код работает без ошибок? По-видимому, закрытие не делало то, что я хочу, поэтому вопрос: как сделать захват аргументов?
Ответы
Ответ 1
Я понял:
SaveCommentEvent firedEvent
given:
...
when:
....
then:
1 * eventBus.fireEvent(_) >> {arguments -> firedEvent=arguments[0]}
firedEvent instanceof SaveModelEvent
firedEvent.newModel == newModel
firedEvent.oldModel == oldModel
Ответ 2
then:
1*eventBus.fireEvent(
{
it.source.getClass()==SaveCommentEvent;
it.oldComment==oldComment;
it.newComment==newComment
}
)
В вашем коде it
есть Groovy Clocure Implicit Variable ссылка на mock eventBus Interface, который не имеет полей. Как вы могли их проверить?
Кроме того, я думаю, что порядок событий, который должен произойти с использованием Spock Mocks, не обязательно интуитивно понятен. Я бы написал его здесь, но это было бы не так хорошо, как объяснение Кеннета Коусона.
Ответ 3
В ответе @alex-luya выше я обнаружил, что для переменной firedEvent
требуется аннотация @Shared
.
Затем я могу захватить значение и выполнить мои проверки значения за пределами замыкания.
Ответ 4
Если вы фиксируете аргумент в методе в явном блоке взаимодействия, тогда аргумент доступен вне замыкания взаимодействия, но не внутри замыкания.
Например:
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
}