1
votes

I have a Domain class called User. When running test I wanted to redefine the get method of the User class by doing the following

User.metaClass.static.get = {Long id -> [username:"joe", id:id]}

But applying the above does not seem to have an impact when I call

User.get(2)

Can I use metaClass in the static Domain GORM methods like get() or list() to change their behavior ? Thanks

Here it is my testCase:

@Test

void testMe(){

  User.metaClass.static.get = { id -> [username:"joe", id:id]}

  def user  = User.get(3)

  assert user.username == "joe"

}

and I get an NPE Cannot get property 'username' on null object

I can actually do it using groovy MockFor

  def mockControl = new MockFor(User.class)

  mockControl.demand.get {id -> return [username:"joe"]}

  mockControl.use {

      def user = User.get(3)

      assert user.username == "joe"
  } 
2
Any reason you do not use available mocking apis? - dmahapatro
@dmahapatro What mocking apis are you referring to? - Julian Bonilla
@Mock is used for domain classes. Are you specifically trying to test User.get works as expected? - dmahapatro
This is in an integration test. I tried actually to put the Mock annotation but I would get "Annotation @grails.test.mixin.Mock is not allowed on element METHOD" - Jorge Fiallega
I'm assuming the real test is bit more complex. If you bypass the GORM database integration... what are you testing? Integration tests don't allow Mock because you're supposed to be adding things to the DB during these tests. - billjamesdev

2 Answers

0
votes

Don't type the closure parameter. If you were to use that method as you've written it you'd need to call User.get(2L), otherwise you're passing an Integer and the signature doesn't match. It should work if you define get as

User.metaClass.static.get = { id -> [username:"joe", id:id]}
0
votes

Try adding the following annotation to your test

@Mock([User])

Then you could do something like this:

def userControl = mockFor(User)
userControl.demand.static.get() {Long id -> return null}