user1918858
user1918858

Reputation: 1208

Verifying non spy method calls with Spock

I want to use spock to find if a method in a class was called. But when I try to verify it, the when block says that the method was never called.

public class Bill {
    public Bill(Integer amount) {
        this.amount = amount;

    }
    public void pay(PaymentMethod method) {
        Integer finalAmount = amount + calculateTaxes();
        method.debit(finalAmount);
    }

    private Integer calculateTaxes() {
        return 0;
    }

    private final Integer amount;
}

public class PaymentMethod {

    public void debit(Integer amount) {
        // TODO
    }

    public void credit(Integer amount) {
        // TODO
    }
}

import spock.lang.Specification
import spock.lang.Subject

class BillSpec extends Specification {
    @Subject
    def bill = new Bill(100)

    def "Test if charge calculated"() {
        given:
        PaymentMethod method = Mock()
        when:
        bill.pay(method)
        then:
        1 * method.debit(100)
        // 1 * bill.calculateTaxes() // Fails with (0 invocations) error
        0 * _
    }
}

In the example above all I want to do is verify if calculateTaxes is being called but the test fails with (0 invocations). I tried using spy but am not sure what would be the syntax since Bill takes a parameterized constructor.

Upvotes: 2

Views: 676

Answers (1)

cgrim
cgrim

Reputation: 5031

You can test calculateTaxes() call when you Spy the Bill instance like this:

class SpyTestSpec extends Specification {
    def "Test if charge calculated"() {
        given:
        def bill = Spy(new Bill(100))
        PaymentMethod method = Mock()

        when:
        bill.pay(method)

        then:
        1 * method.debit(100)
        1 * bill.calculateTaxes()
        1 * bill.pay(method)
        0 * _
    }
}

Another important thing is to make calculateTaxes() method visible for the test, otherwise it will still fail:

public Integer calculateTaxes() { ... }

Note that if you want to test that nothing else was called then you should also add:

1 * bill.pay(method)

And here is the result: enter image description here

Upvotes: 3

Related Questions