DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations

Trending

  • Health Check Response Format for HTTP APIs
  • Microservices With Apache Camel and Quarkus (Part 2)
  • Introduction To Git
  • Authorization: Get It Done Right, Get It Done Early

Trending

  • Health Check Response Format for HTTP APIs
  • Microservices With Apache Camel and Quarkus (Part 2)
  • Introduction To Git
  • Authorization: Get It Done Right, Get It Done Early

Spocklight: Writing Assertions for Arguments Mock Methods

Hubert Klein Ikkink user avatar by
Hubert Klein Ikkink
·
May. 21, 13 · Interview
Like (0)
Save
Tweet
Share
13.66K Views

Join the DZone community and get the full member experience.

Join For Free

My colleague Arthur Arts has written a blog post Tasty Test Tip: Using ArgumentCaptor for generic collections with Mockito. This inspired me to do the same in Spock. With the ArgumentCaptor in Mockito the parameters of a method call to a mock are captured and can be verified with assertions. In Spock we can also get a hold on the arguments that are passed to method call of a mock and we can write assertions to check the parameters for certain conditions.

When we create a mock in Spock and invoke a method on the mock the arguments are matched using the equals() implementation of the argument type. If they are not equal Spock will tell us by showing a message that there are too few invocations of the method call. Let's show this with an example. First we create some classes we want to test:

package com.mrhaki.spock

public class ClassUnderTest {

    private final Greeting greeting

    ClassUnderTest(final Greeting greeting) {
        this.greeting = greeting
    }

    String greeting(final List<Person> people) {
        greeting.sayHello(people)
    }
}
package com.mrhaki.spock

interface Greeting {
    String sayHello(final List<Person> people)
}
package com.mrhaki.spock

@groovy.transform.Canonical
class Person {
    String name
}    

Now we can write a Spock specification to test ClassUnderTest. We will now use the default matching of arguments of a mock provided by Spock.

package com.mrhaki.spock

import spock.lang.Specification

class SampleSpecification extends Specification {

    final ClassUnderTest classUnderTest = new ClassUnderTest()

    def "check sayHello is invoked with people in greeting method"() {
        given:
        final Greeting greeting = Mock()
        classUnderTest.greeting = greeting

        and:
        final List<Person> people = ['mrhakis', 'hubert'].collect { new Person(name: it) }

        when:
        final String greetingResult = classUnderTest.greeting(people)

        then:
        1 * greeting.sayHello([new Person(name: 'mrhaki'), new Person(name: 'hubert')])
    }

}

When we execute the specification we get a failure with the message that there are too few invocations:

...
Too few invocations for:

1 * greeting.sayHello([new Person(name: 'mrhaki'), new Person(name: 'hubert')])   (0 invocations)

Unmatched invocations (ordered by similarity):

1 * greeting.sayHello([com.jdriven.spock.Person(mrhakis), com.jdriven.spock.Person(hubert)])
...

To capture the arguments we have to use a different syntax for the method invocation on the mock. This time we define the method can be invoked with any number of arguments ((*_)) and then use a closure to capture the arguments. The arguments are passed to the closure as a list. We can then get the argument we want and write an assert statement.

package com.mrhaki.spock

import spock.lang.Specification

class SampleSpecification extends Specification {

    final ClassUnderTest classUnderTest = new ClassUnderTest()

    def "check sayHello is invoked with people in greeting method"() {
        given:
        final Greeting greeting = Mock()
        classUnderTest.greeting = greeting

        and:
        final List<Person> people = ['mrhakis', 'hubert'].collect { new Person(name: it) }

        when:
        final String greetingResult = classUnderTest.greeting(people)

        then:
        1 * greeting.sayHello(*_) >> { arguments ->
            final List<Person> argumentPeople = arguments[0]
            assert argumentPeople == [new Person(name: 'mrhaki'), new Person(name: 'hubert')]
        }
    }

}

We run the specification again and it will fail again (of course), but this time we get an assertion message:

...
Condition not satisfied:

argumentPeople == [new Person(name: 'mrhaki'), new Person(name: 'hubert')]
|              |   |                           |
|              |   |                           com.jdriven.spock.Person(hubert)
|              |   com.jdriven.spock.Person(mrhaki)
|              false
[com.jdriven.spock.Person(mrhakis), com.jdriven.spock.Person(hubert)]

    at com.jdriven.spock.SampleSpecification.check sayHello is invoked with people in greeting method_closure2(SampleSpecification.groovy:25)
...

Code written with Spock 0.7-groovy-2.0



 

Assertion (software development)

Published at DZone with permission of Hubert Klein Ikkink, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Trending

  • Health Check Response Format for HTTP APIs
  • Microservices With Apache Camel and Quarkus (Part 2)
  • Introduction To Git
  • Authorization: Get It Done Right, Get It Done Early

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: