3
votes

Getting grailsApplication as null when running spock test cases using UnitSpec for service class in Grails application.

Error - Cannot get property 'config' on null object

Can anybody tell me how to configure grailsApplication while spock testing service classes.

I have googled a lot, but didn't solve my problem.

Here is the code.

  def accountServiceMock = Mock(AccountService)
    def accountClientService = new AccountClientService()
def setup(){

    accountClientService.accountWS = accountServiceMock
    accountClientService.basicAuthInterceptor = authenticatorServiceMock        
}

def "test account by status() " (){
    setup:
    def mockAccountStatus = "ACTIVE"
    mockDomain(Account, [accountInstance])
    accountClientService.grailsApplication = grailsApplication

    when:
    accountClientService.getAccountByStatus(mockAccountStatus)  //calling web service by fetching url from default.properties file which is context

    then:
    Account.count() != 0

    where:
    accountInstance = new Account(10L, "ACTIVE","1234", "firstName", "LastName")
}

In AccountService class getAccountByStatus() method calling webservice with url = grailsApplication.config.ACCOUNTWEBSERVICEURL which is there default.properties file but when i run spock test case it is throwing error like

Cannot get property 'config' on null object

2
Can you post the code of your test, maybe helps to see what's going on. - user800014
Which Grails version? Which Spock version? - Peter Niederwieser
Are you doing a unittest or integrationtest? By the looks of it you want to do an integrationtest. If that's true look here grails.org/doc/2.2.0/guide/single.html#integrationTesting to correctly implement the test - Bart

2 Answers

3
votes

Here you go:

import spock.lang.Specification
import grails.test.mixin.*

@TestFor(SomeService)
class SomeServiceIntegrationSpecSpec extends Specification {

    def "give me the config value"() {
        given: config.value = '123'
        expect: service.valueFromConfig == '123'
    }
}

...and just for the reference, the SomeService class:

class SomeService {

    def grailsApplication // autowired

    def getValueFromConfig() {
        grailsApplication.config.value
    }
}

Above example is stupid simple, though enough to show how it should be done. Autowiring of grailsApplication works thanks to @TestFor annotation. If this doesn't fit you case more info will be necessary:

  • Grails version
  • Spock version (grails plugin version will do)
  • where from NPE is thrown? the tested service itself or a mock
  • is it grails unit or integration test
  • full test source will be hepful

No mater what exact is your case, you can always just mock the config like answered here by j4y (last answer at current time)

If you are unit-testing keep in mind that Config.groovy is not slurped. Another thing worth mentioning, if the NPE is thrown from object created by Mock() or 'new' keyword it's no surprise as no autowiring there.

1
votes

I had a similar issue. Actually had a domain object that was referencing grailsApplication.

Fixed by assigning grailsApplication from test to domain:

@TestMixin(GrailsUnitTestMixin)
@TestFor(MyService)
@Mock([MyDomain])
class MyServiceSpec extends Specification {

    myTest() {

        grailsApplication.config.myValue = "XXX"

        def myDomain = MyDomain()

        myDomain.grailsApplication = grailsApplication

    }
}