Grails String.encodeAsBase64() Fails in Spock Tests

984 Views Asked by At

This code works fine when I run it in Grails.

String getLoginToken() {
    generatePassword()
    passwordExpired = false
    [email, password].join(',').encodeAsBase64()
}

However, this Spock test fails

def "test getLoginToken"() {
    setup:
    String email = "[email protected]"
    Person person = new Person(email: email)

    when:
    String token = person.getLoginToken()

    then:
    token.decodeBase64() == "$email,$person.password"
}

with the following exception

| Failure:  test getLoginToken(com.campuscardtools.myphotoid.PersonSpec)
|  groovy.lang.MissingMethodException: No signature of method: java.lang.String.encodeAsBase64() is applicable for argument types: () values: []
Possible solutions: decodeBase64()
    at com.campuscardtools.myphotoid.Person$$EPFScS6i.getLoginToken(Person.groovy:140)
    at com.campuscardtools.myphotoid.PersonSpec.test getLoginToken(PersonSpec.groovy:68)

My understanding is that Groovy provides the encodeAsBase64() on the String class (see: http://mrhaki.blogspot.com/2009/11/groovy-goodness-base64-encoding.html), so why doesn't this work in the unit test?

3

There are 3 best solutions below

2
On BEST ANSWER

Rather than

"Blah".encodeAsBase64()

You need

"Blah".encodeBase64()

Without the 'As'

0
On

This works, but I fells like a bad hack. Surely there must be cleaner solution:

def cleanup () {
    String.metaClass = null
}

def "test getLoginToken"() {
    setup:
    String email = "[email protected]"
    Person person = new Person(email: email)
    String encoded = null

    and:
    String.metaClass.encodeAsBase64 {
        encoded = delegate
        return delegate
    }

    when:
    String token = person.getLoginToken()

    then:
    token == "$email,$person.password"
    encoded == "$email,$person.password"
}
0
On

You could also include a mockCodec for the method you're using.

and: "add the Base64 codec"
    mockCodec(org.codehaus.groovy.grails.plugins.codecs.Base64Codec)