Category Archives: Spock

Guava: Testing equals(..) and hashcode(..)

PROBLEM

Let’s assume we want to test the following equals(..):-

public class Person {
    private String name;
    private int age;

    @Override
    public boolean equals(Object o) {
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        Person person = (Person) o;
        return Objects.equal(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(name);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

A correctly implemented equals(..) must be reflexive, symmetric, transitive, consistent and handles null comparison.

In another word, you have to write test cases to pass at least these 5 rules. Anything less is pure bullshit.

SOLUTION

You can write these tests yourself… or you can leverage Guava’s EqualsTester. This library will test these 5 rules and ensure the generated hashcode matches too.

First, include the needed dependency:-

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava-testlib</artifactId>
    <version>18.0</version>
    <scope>test</scope>
</dependency>

Instead of writing JUnit tests, I’ll be writing Spock specs, which is essentially built on top of Groovy, because it allows me to write very clear and clean tests.

class PersonSpec extends Specification {

    def person = new Person(name: 'Mike', age: 10)

    def "equals - equal"() {
        when:
        new EqualsTester().
                addEqualityGroup(person,
                                 new Person(name: 'Mike', age: 10),
                                 new Person(name: 'Mike', age: 20)).
                testEquals()

        then:
        notThrown(AssertionFailedError.class)
    }

    def "equals - not equal"() {
        when:
        new EqualsTester().
                addEqualityGroup(person,
                                 new Person(name: 'Kurt', age: 10)).
                testEquals()

        then:
        thrown(AssertionFailedError.class)
    }
}

Oh… wait for it… BOOM!

Advertisements

Spock: Reading Test Data from CSV File

Following up on my recent post about creating a Spock specification to read the test data from a CSV file without loading all the data into the memory, I created a CSVReader that implements Iterable that allows me to pull this off. You may download the source code here.

With this implementation, I can now write an elegant Spock specification:-

class MySpockSpec extends Specification {
    @Unroll
    def "#firstNum + 1 == #secondNum"() {
        expect:
        Integer.valueOf(firstNum as String) + 1 == Integer.valueOf(secondNum as String)

        where:
        [firstNum, secondNum] << new CSVReader(getClass().getClassLoader().getResourceAsStream("test.csv"))
    }
}

Maven: Unable to Execute Spock Specs

PROBLEM

When running mvn clean test, Maven Surefire Plugin doesn’t pick up *Spec.groovy test files.

SOLUTION

By default, Maven Surefire Plugin is configured to execute test files with the following patterns: **/Test*.java, **/*Test.java and **/*TestCase.java.

To fix this, we need to modify the inclusion list for this plugin. Since both Java and Groovy files get compiled down to *.class, it is probably easier to just include *.class instead of *.java or *.groovy.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.17</version>
    <configuration>
        <includes>
            <include>**/Test*.class</include>
            <include>**/*Test.class</include>
            <include>**/*TestCase.class</include>
            <include>**/*Spec.class</include>
        </includes>
    </configuration>
</plugin>