Question

I have some Java stuff like this:

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(){...}
}

and test code like this:

  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
                                 }
                              )            
}

I want to verify that the eventBus.fireEvent(..) gets called once with an Event with type SaveCommentEvent and construction parameters oldComment and newComment.

Code runs without errors but problem is:

After changing closure stuff from

{
   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
  }

Still, code runs without error? Apparently the closure didn't do what I want, so the question is: How to do argument capturing?

Was it helpful?

Solution

I got it:

    SaveCommentEvent firedEvent

    given:
     ...

    when:
     ....

    then:
    1 * eventBus.fireEvent(_) >> {arguments -> firedEvent=arguments[0]}
    firedEvent instanceof SaveModelEvent
    firedEvent.newModel == newModel
    firedEvent.oldModel == oldModel

OTHER TIPS

then:
     1*eventBus.fireEvent(
                            {
                               it.source.getClass()==SaveCommentEvent;
                               it.oldComment==oldComment;
                               it.newComment==newComment
                             }
                          )            

In your code it is a Groovy Closure Implicit Variable reference to a mock eventBus Interface which has no fields. How could you verify them?

Also, I think the order of events that has to happen to use Spock Mocks is not necessarily intuitive. I would write it up here except it would not be as good as Kenneth Kousen's explanation.

Same idea with @Alex Luya but put the assertions in the closure and use assert on each of them. 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
    }

In 2021 (7 yrs later) it is possible to do the following with groovy (2.5):

    ...

    then:
    1 * eventBus.fireEvent(_) >> { SaveModelEvent event ->
        assert event.newModel == newModel
        assert event.oldModel == oldModel
    }
    0 * _

.. which feels more handy to me and saves a line or two. :)

In the answer from @alex-luya above, I found that the variable firedEvent needs the @Shared annotation.

Then I can capture the value and run my checks on the value outside the closure.

If you want to mock a method's response and also verify the same method's params(same as capturing the params), you can use Spock's code constraints (among other constraints) to partially match params, and at the same time, verify the method params. :

1 * list.add({
  verifyAll(it, Person) {
    firstname == 'William'
    lastname == 'Kirk'
    age == 45
  }
}) >> mockedResponse

PS: Solution inspired by this response from @Leonard Brünings

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top