apache / apache/grails-core

Mock domain collections fail to save properly when combined with @EqualsAndHashcode

Open
#14,633 1 comment 0 reactions 0 assignees View on GitHub
info: workaround available relates-to: gorm
Dominant language
Groovy
Stars
2.9k
Forks
975
Avg merge
1d 22h
Merged PRs (30d)
92

Description

Example: https://github.com/joemccall86/grails-domain-equals-hashcode-test

If there's a one-to-many relationship between 2 simple GORM classes, and the many-side has the `@EqualsAndHashcode` annotation, unit tests do not behave as expected. Specifically calling `addTo` on the "one" side will append the collection, and subsequently calling `save` will append the collection again. See the example attached. Important code is copied below for your convenience.

Domain classes:

``` groovy
class Author {

static hasMany = [
books: Book
]

static constraints = {
}
}
```

``` groovy
import groovy.transform.EqualsAndHashCode

@EqualsAndHashCode
class Book {

static constraints = {
}

static belongsTo = [
author: Author
]
}
```

Test:

``` groovy
@Mock([
Book,
Author
])
@TestFor(Author)
class AuthorSpec extends Specification {

void "test that we can add to books"() {
given: 'an author'
def author = new Author().save(flush: true, failOnError: true)

and: 'a book is added'
author.addToBooks(new Book())

when: 'the author is saved'
author.save(failOnError: true)

then: 'the author only has 1 book'
author.books.size() == 1
}
}
```

The test fails with:

```
Condition not satisfied:

author.books.size() == 1
| | | |
| | 2 false
| [org.grails.Book : 1, org.grails.Book : 1]
org.grails.Author : 1

at org.grails.AuthorSpec.test that we can add to books(AuthorSpec.groovy:34)
```

I can only speculate as to why it's happening. This test does not seem to break when run as an integration test, indicating it's a problem with `@Mock`-ed domain classses.

Contributor guide

Open the contributing guide

Research direction

Start with the attached example repository and its AuthorSpec test, reproducing the one-to-many Author/Book case with @Mock and @EqualsAndHashCode. Compare the unit-test behavior with the integration-test behavior described in the issue. Done means saving after addToBooks leaves exactly one book and the regression test passes.

Written by the indexing model from the issue text.

Assessment

Tech stack
groovy
Domain
testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.