Spock test framework: Difference between mock.getProperty('name') vs getName()

Viewed 172

What is the difference in a mocked instance between getProperty('name') vs getName()? I thought they meant the same thing but I keep having to swap between them because sometimes spock isn't happy with one or the other.

Let's say I have the following class

class Person {
    String name
}

And I'm testing some other class that is meant to update the person so I do something like this:

void "test something"() {
    Person personMock = Mock(Person)

    when:
    someObject.updatePersonName(personMock, 'new name')

    then:
    1 * personMock.getName() >> 'old name'
    1 * personMock.setName('new name')
}

The details of the simplified test aren't important. The point is that I'm verifying that a certain property is being read and updated. Sometimes when I run the tests I get complaints that personMock.getName() was never called and it helpfully shows that personMock.getProperty('name') was called instead. The test passes if I rewrite it to use that form. Until some time later it again complains that getProperty('name') wasn't called but getName() was.

I know that spock can't possibly be this flaky. I must have fumbled somewhere. So when should I use getName() and when getProperty('name')?

1 Answers

It is strange that your code flip-flops, however if your are testing Groovy code then you should use GroovyMock instead of Mock (see also docs), it has extra support for some of Groovys special features.

When Should Groovy Mocks be Favored over Regular Mocks? Groovy mocks should be used when the code under specification is written in Groovy and some of the unique Groovy mock features are needed. When called from Java code, Groovy mocks will behave like regular mocks. Note that it isn’t necessary to use a Groovy mock merely because the code under specification and/or mocked type is written in Groovy. Unless you have a concrete reason to use a Groovy mock, prefer a regular mock.

In this case you (or your code) are using some of Groovys special features, i.e., the Groovy MOP method getProperty. GroovyMock uses the GroovyMockInterceptor which handles these special methods, e.g., normalizing getProperty('x') to getX().

void "test something"() {
    Person personMock = GroovyMock(Person)

    when:
    someObject.updatePersonName(personMock, 'new name')

    then:
    1 * personMock.getName() >> 'old name'
    1 * personMock.setName('new name')
}
Related