Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test a grails Criteria query?

first post here and hopefully relevant to many people.

I'm working on writing integration tests for a domain and on that domain I have a query using the withCriteria() method. I've searched all over the net and found many that give you detailed instructions on how to go about mocking a criteria query, but none on how to exactly test it.

I've tried mocking the domain using the mockDomain(domain,list) function, and setting up a domain for the test to use in the setUp() then calling the criteria and I get nothing. I did a similar findBy here and got the results, but not exactly the ones I was looking for. I'm pretty sure it's not just my query, but the criteria, I've read in a few places criteria does not work in service testing. The query thus far has worked for me in the app, but I want to have some tests that I can refer to later in case my code base changes.

I've actually done as many have suggested and pulled out the code for the query and made it a static method in my domain so that I can mock it for the tests that use it, but now I'm stuck with how to actually test this part. Do I need to run the app and just do functional testing from that standpoint, or is there some way I could do this in the grails unit/integration testing. I'll post my query below.

static Attribute getDefinitionsUsingCriteria(List categoryNames, List types){
        def definitions = Definition.withCriteria() {
            and {
                'in'('type', types)
                if (categoryNames) {
                    categories {
                        'in'('name', categoryNames)
                    }
                }
            }
        }
        return definitions
    }

Definitions has a string property type, and has a property categories of type Set that each element in this set has a String name property.

I'm still pretty new to grails and have been reading many reference books, and I'm surprised this is missing in all of the books I've read thus far. I hope this is something that is just a mistake on my part, and easily testable. I appreciate any help, and thanks for reading this long post.

JR.

like image 861
kman Avatar asked Jun 03 '11 21:06

kman


2 Answers

One way: move the test from test/unit to test/integration folder. Criteria won't work in unit test (there's no Hibernate there), but will in integration. Never use mockDomain() in integration tests.

Note: don't make the method static - it only complicates testing.

Second way: In unit tests - use mockDomain(). Just rely on the fact that the logic is pretty straightforward, and unit-test everything except the method. Override it in setUp() like:

Definition.metaClass.getDefinitionsUsingCriteria = { List categoryNames, List types ->
    delegate.findAll{ (it.type in types) && 
        (it.categories.find { c -> c in categoryNames }) 
    }
}
like image 99
Victor Sergienko Avatar answered Oct 22 '22 01:10

Victor Sergienko


Grails 2.0.1 now has native @Mock for test criteria, but groupProperty is not implemented yet.

I wrote mock criteria plugin (with groupProperty)

https://github.com/fabiooshiro/plastic-criteria

it works in 1.3.7

like image 23
Sr. Oshiro Avatar answered Oct 22 '22 00:10

Sr. Oshiro