开发者

Grails - Unit test a controller's method using the reCaptcha plugin

开发者 https://www.devze.com 2023-04-08 05:01 出处:网络
I would like to unit test the following method: def handleEmailSharing = { EmailSharingCommand esc ->

I would like to unit test the following method:

def handleEmailSharing = { EmailSharingCommand esc ->
        if (params.send) {
            def recaptchaOK = true
            if (!recaptchaService.verifyAnswer(session, request.getRemoteAddr(), params)) {
                recaptchaOK = false
            }

         }
...

This is the way I am trying to do it:

import com.megatome.grails.R开发者_StackOverflow中文版ecaptchaService

class EmailSharerControllerTests extends ControllerUnitTestCase {

    protected void setUp() {
     controller.recaptchaService = new RecaptchaService()
   }

void testHandleEmailSharingSendAndSuccess() {
       mockCommandObject(EmailSharingCommand)
        def emailSharingCommand = new EmailSharingCommand(from: "acorrect@emailaddress.fr", 
                                                          to: "   anothercorrect@emailaddress.fr   ,    whichis@notalone.it   ", 
                                                          cc: "", 
                                                          bcc:"someonein@bcc.com.br",
                                                          trimmedListOfToRecipients: ["anothercorrect@emailaddress.fr", "whichis@notalone.it"])
        emailSharingCommand.validate()
}
controller.handleEmailSharing(emailSharingCommand)

But I get the following error:

Cannot get property 'recaptcha' on null object
java.lang.NullPointerException: Cannot get property 'recaptcha' on null object
    at com.megatome.grails.RecaptchaService.getRecaptchaConfig(RecaptchaService.groovy:33)
    at com.megatome.grails.RecaptchaService.this$2$getRecaptchaConfig(RecaptchaService.groovy)
    at com.megatome.grails.RecaptchaService$this$2$getRecaptchaConfig.callCurrent(Unknown Source)
    at com.megatome.grails.RecaptchaService.isEnabled(RecaptchaService.groovy:100)
    at com.megatome.grails.RecaptchaService$isEnabled.callCurrent(Unknown Source)
    at com.megatome.grails.RecaptchaService.verifyAnswer(RecaptchaService.groovy:81)
    at com.megatome.grails.RecaptchaService$verifyAnswer.call(Unknown Source)
    at bankemist.personalcreditcomparator.EmailSharerController$_closure2.doCall(EmailSharerController.groovy:49)
    at bankemist.personalcreditcomparator.EmailSharerControllerTests.testHandleEmailSharingSendButtonButMissingFromAndTo(EmailSharerControllerTests.groovy:49)

Which is strange, because it basically says that my org.codehaus.groovy.grails.commons.ConfigurationHolder is null, or the recaptcha object it contains. The call line 33 of RecaptchaService.groovyis:

if (ConfigurationHolder.config.recaptcha) {...}

Or (last one :) ) this how my RecaptchaConfig.groovy is set:

recaptcha {
    // These keys are generated by the ReCaptcha service
    publicKey = "xxx"
    privateKey = "xxx"

    // Include the noscript tags in the generated captcha
    includeNoScript = true
}

mailhide {
    // Generated by the Mailhide service
    publicKey = ""
    privateKey = ""
}

environments {
  development {
    recaptcha {
      // Set to false to disable the display of captcha
      enabled = true

      // Communicate using HTTPS
      useSecureAPI = false
    }
  }
  test {
    recaptcha {
      // Set to false to disable the display of captcha
      enabled = true

      // Communicate using HTTPS
      useSecureAPI = false
    }
  }

I do not manage to work around this issue. I have tried to import the configurationHolder into the test file but it does not chage anything. Any help greatly appreciated.


Unit tests will not have ConfigurationHolder because they are not executed inside the running framework. In unit tests the best option is to mock the RecaptchaService, so like this inside your test method:

def recapMock = mockFor(RecaptchaService)
recapMock.demand.verifyAnswer(1..1) { session, remoteAddr, params ->
     return true // Or false if you want it to fail in your test
}
controller.recaptchaService = recapMock.createMock()
// Then run your test
controller.handleEmailSharing(emailSharingCommand)


You should inject a recaptchaService and mock the verifyAnswer to return whatever you want to return for your test case.

     def recaptchaServiceMock = mockFor(recaptchaService)

            recaptchaServiceMock.demand.verifyAnswer() {Session session, 
                                                        Map params->
                return true
            }

      currentService.recaptchaService = recaptchaServiceMock.createMock()
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号