Psycho Punch
Psycho Punch

Reputation: 6892

How do I verify method is invoked in the correct order among mock objects in Spock?

In my unit tests, I have 2 Mock objects, let's call them Book book and Shelf shelf. I want to ensure that the repair() method if the book is called first by the piece of code I'm testing before it is put back to the shelf via putBack(Book) method of Shelf class.

Here's a quick illustration:

def "Organize damaged books"() {

    given:
    Book book = Mock(Book)
    Shelf shelf = Mock(Shelf)

    when:
    library.returnDamaged(book)

    then:
    1 * book.repair()
    1 * shelf.putBack(book)

}

The test above will pass even if in the returnDamaged method, I call shelf.putBack() first before book.repair(). I tried doing:

1 * shelf.putBack(book) >> {
    1 * book.repair()
}

But the test still passes regardless of which comes first.

Upvotes: 1

Views: 1140

Answers (1)

dpcasady
dpcasady

Reputation: 1846

From Spock's documentation on Interaction Based Testing:

To avoid over-specification, Spock defaults to allowing any invocation order, provided that the specified interactions are eventually satisfied…in those cases where invocation order matters, you can impose an order by splitting up interactions into multiple then: blocks.

So if you want to enforce invocation order, all you need to do is split the assertion into multiple then blocks:

then:
1 * book.repair()

then:
1 * shelf.putBack(book)

Upvotes: 4

Related Questions