Mock domain collections fail to save properly when combined with @EqualsAndHashcode
- 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
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