4

The output of my test gives com.example.book.Book : null. When I debug the test, b object is created with "MyBook" as its name. But since its has a static mapping belongsTo, the test fails. How do I make this work. When I comment the belongsTo mapping in the Books.groovy, the test passes. So how do I test Domain classes with mappings. Should I instantiate a Library object and add a Book object to it? But that doesn't make testing the domain class in isolation as it is meant to be in a unit test, does it?

Below is my code.

Domains:

//Book.groovy
package com.example.book

class Book {
    static constraint = {
        name blank: false, size: 2..255, unique: true
    }
    static belongsTo = [lib: Library]
    String name
}

//Library.groovy
package com.example.library

class Library {
    static hasMany = [book: Book, branch: user: User]
    static constraints = {
        name blank: false
        place blank: false
    }
    String name
    String place
}

Unit tests:

//BookUnitTests.groovy
package com.example.book

import grails.test.*

class BookUnitTests extends GrailsUnitTestCase {
    protected void setUp() {
        super.setUp()
        mockForConstraintsTests(Book)
    }

    protected void tearDown() {
        super.tearDown()
    }

    void testPass() {
        def b = new Book(name: "MyBook")
        assert b.validate()
    }
}

Test Output:

Failure:  testPass(com.example.book.BookUnitTests)
|  Assertion failed: 

assert b.validate()
       | |
       | false
       com.example.book.Book : null

       at com.example.book.BookUnitTests.testPass(BookUnitTests.groovy:17)

Thanks.

1 Answers1

2

Yes, the way you have this set up the Book cannot exist without a Library. You will have to create a Library and assign the book to it.

Whether using belongsTo makes sense depends on your requirements. Do you really need to save the library and have all the books get saved as a result?

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
  • 1
    I can't change the domain classes. Thanks for the answer. It made me think in the right direction. I have to create a `Library` object and assign it to the `Book` object during the initialization of Book object like: `def l = new Library(name: "a", place: "p"); def b = new Book(name: "myBook", lib: l);` and then do `b.validate()` which passes the test. Phew!! Spent whole day figuring it out. The grails guys could have documented it. –  Mar 22 '12 at 18:36
  • Should all the unit testing for Book go in LibraryUnitTests or should it be spread between two test classes? – Alison Dec 18 '12 at 18:13
  • @Allison: for integration tests with the current design you're stuck. for non-persistence-related unit tests you can do whatever makes sense. – Nathan Hughes Dec 18 '12 at 19:16