1
votes

Using spock I need to mock the calls to EntityManager/Query. The line of code I'm trying to mock is:

entityManager.createNativeQuery("nativeQuery").setParameter(1, param1).getResultList()

The mock of entityManager.createNativeQuery returns a null Query object. That then causes a failure because you can't call a method on a null object. And I consequently I can't mock the return of a result set list.

I've tried breaking the statement down into separate ones and accompanying mocks, but that hasn't worked either because I still end up with a null Query.

I don't know if I've got tunnelvision on this right now, or if this can't be mocked - at least with Spock.

All help appreciated!

1

1 Answers

2
votes

What you need to do is to build a hierarchy of mocks which will be returning each other, starting with the last one:

Query:

def query = Mock(Query) {
   setParameter(_, _) >> it //here as mock itself is returned
   getResultList() >> []    //empty list
}

EntityManager:

def manager = Mock(EntityManager) {
   createNativeQuery(_) >> query
}

And so on. While what you need to implement is doable it more or less indicates bad design: every time a mock returns a mock a fairy dies, so you should avoid such constructs. What you can do is to separate query building from it's execution - then mocking will be much easier. Sample spec:

def 'fairy has just died'() {
   given:
   def query = Mock(Query) {
      setParameter(_, _) >> it //here as mock itself is returned
      getResultList() >> [1]    //empty list
   }

   def manager = Mock(EntityManager) {
      createNativeQuery(_) >> query
   }

   expect:
   manager.createNativeQuery("").setParameter(1,1).getResultList() == [1]
}