views:

55

answers:

2

I'm staring a toy project with Grails, but I'm having some trouble regarding the HSQLDB database. My DataSource.groovy file is the default one:

environments {
    development {
        dataSource {
            dbCreate = "create-drop" // one of 'create', 'create-drop','update'
            url = "jdbc:hsqldb:mem:devDB"
            loggingSql = true
        }
    }
    test {
        dataSource {
            dbCreate = "update"
            url = "jdbc:hsqldb:mem:testDb"
            loggingSql = true
        }
    }
    production {
        dataSource {
            dbCreate = "update"
            url = "jdbc:hsqldb:file:prodDb;shutdown=true"
        }
    }
}

And I'm running a Simple test:

class BookTests extends GrailsUnitTestCase {
    protected void setUp() {
        super.setUp()

        mockDomain (Book)
        def book = new Book ("The shinning","Some guy who wrote it")
        if (book.save()){
            println ("YEAH")
        }
        else{
            print ("AWWWWHH")
        }
    }

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

    void testSomething() {
        def books = Book.getAll()
        print (books.size())
    }
}

After the book.save() in the setUp() method, I get a "YEAH", but in the testSomething() method, the books.size() turns out to be 0.

1 test class found in package 'test'

YEAH 0 Process finished with exit code

0

Am I overlooking something? I was under the impression that this HSQLDB was set up for development testing, but I've been having some trouble in both environments (either with this test, or with a very simple app.)

+1  A: 

Use book.save(flush: true) because calling save() only registers this object to be saved by hibernate at some point in the future - for example on the end of a transaction.

Read more about this here: http://grails.org/doc/latest/guide/single.html#5.3.1 Saving and Updating

Edit: I found the grails.test.MockUtils.groovy to be implemented incorrectly for getAll(). There are is no implementation that handles a parameterless call correctly. You could overcome this with a simple fix. See attached sample:

package sandbox

import grails.test.*

class BookTests extends GrailsUnitTestCase {

  protected void setUp() {
    super.setUp()
    // test data setup
    def bookInstances = [
            new Book(title: "Grails", author: "Graeme"),
            new Book(title: "Spring", author: "Rod")
    ]
    mockDomain Book, bookInstances
    new Book(title: "The shinning", author: "Some guy who wrote it").save(flush: true)

    // fixing parameterless getAll() behaviour through delegating to findAll()
    registerMetaClass Book
    Book.metaClass.'static'.getAll = {-> Book.findAll() }
  }

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

  void testSomething() {
    assert Book.getAll().size() == 3
    assert Book.findAll().size() == 3
  }

}
codescape
+1  A: 

You are using a unit test. It won't save anything to the database. You are mocking the domain, so Grails will do some stuff to make it look like you have some persistence methods available, but nothing goes to the database. If you want that, write an integration test.

So in answer to your question, you are not having trouble with your database. You are having trouble getting started with the unit testing.

The advice for flush by @codescape is good too.

hvgotcodes