Mocking Hibernate Criteria in Grails App

Testing is always a sore spot in many applications, and Grails is no exception, but mocking objects and methods is actually not as bad as you think. Here is a simple way to mock the Hibernate Criteria object that is available from Grails domain classes.

Example:
If this is the code that you want to test, and for this particular test you want to have no results, this how you would mock it out.

Code:


Test Code:


The key piece of code is the creation of the bookCriteria object, in this case it is a member of the test class that is why it is not declared locally in the function. However, you will notice that the bookCriteria is simply a HashMap that returns a empty list for the 'list' parameter. This way when testing 'c.list' a empty list will be returned. Simple hunh!

8 comments:

  1. how to make test unit if we have server ldap ??

    ReplyDelete
  2. You saved my life!

    ReplyDelete
  3. You'll need to remove the metaClass override if you need the real implementation in your integration tests.

    GroovySystem.metaClassRegistry.removeMetaClass(Book.class)

    ReplyDelete
  4. Hi, Thanks for the info. I am trying to do mocking of executeQuery but no success, can you please help me with an example of it.

    +Ket

    ReplyDelete
  5. See my newest post about mocking Criteria Objects: here

    In order to do a mock of executeQuery, you would have the following:

    def results = ["Author1", "Author2"]
    mock(Book).static.executeQuery("select distinct b.author from Book b").returns(results)

    ReplyDelete
  6. Hii...
    I have trouble with mocking executeQuery.
    I've modified the code like this:
    def newuserRole=UserRole.create(user,role)
    mockDomain(UserRole).static.executeQuery("DELETE FROM UserRole WHERE user= :user",[user: user]).returns(newuserRole)

    But it still error. Please help me, is there anything wrong with my code??

    ReplyDelete
  7. Thanks for this, two years later - I know this seems more like the kind of thing that should be in an integration test, but for my purposes just now it's perfect!

    ReplyDelete