2011-03-11 8 views
5

Estoy trabajando en un tutorial de Grails de InfoQ llamado Getting Started With Grails, Second Edition, y estoy tratando de agregar un códec personalizado a una prueba de unidad. Mi entorno es Grails 1.3.7 y Groovy 1.7.8.Cómo usar un códec personalizado en una prueba de unidad de Grails

El códec es SHACodec.groovy y vive en grails-app/utils. El contenido es:

import java.security.MessageDigest 

class SHACodec{ 
    static encode = {target-> 
    MessageDigest md = MessageDigest.getInstance('SHA') 
    md.update(target.getBytes('UTF-8')) 
    return new String(md.digest()).encodeAsBase64()  
    }  
} 

El códec funciona bien cuando inicio sesión en la aplicación. Está siendo usado para un campo de contraseña en mi UserController.authenticate()

def authenticate = { 
    def user = 
      User.findByLoginAndPassword(params.login, params.password.encodeAsSHA()) 
     if(user){ 
     session.user = user 
      flash.message = "Hello ${user.login}!" 
     redirect(controller:"race", action:"list")  
     }else{ 
     flash.message = "Sorry, ${params.login}. Please try again." 
      redirect(action:"login") 
    }   
    } 

Cuando agrego esto a una prueba de unidad, aparece el siguiente error:

Sin dicha propiedad: SHACodec para la clase: racetrack.UserControllerTests groovy.lang.MissingPropertyException: Sin dicha propiedad: SHACodec para la clase: racetrack.UserControllerTests en racetrack.UserControllerTests.testAuthenticate (UserControllerTests.groovy: 39)

La prueba es:

package racetrack 

import org.codehaus.groovy.grails.plugins.codecs.* 
import grails.test.* 

class UserControllerTests extends ControllerUnitTestCase { 
    protected void setUp() { 
     super.setUp() 

     String.metaClass.encodeAsSHA = {-> 
      SHACodec.encode(delegate) 
     } 
    } 

    protected void tearDown() { 
     super.tearDown() 
    } 

void testAuthenticate(){ 

    def jdoe = new User(login:"jdoe", password:"password".encodeAsSHA()) 
    mockDomain(User, [jdoe]) 

    controller.params.login = "jdoe" 
    controller.params.password = "password" 
    controller.authenticate() 
    assertNotNull controller.session.user 
    assertEquals "jdoe", controller.session.user.login 

    controller.params.password = "foo" 
    controller.authenticate() 
    assertTrue controller.flash.message.startsWith( 
    "Sorry, jdoe")  
} 

me encontré con dos diferentes recomendaciones hasta el momento. En primer lugar, llamar al códec directamente de la prueba:

SHACodec codec = new SHACodec() 
codec.encode("password") 

En segundo lugar, utilizar una prueba de integración en lugar de una prueba unitaria.

Los resultados fueron los mismos para cada opción. ¿Qué es lo pequeño que me estoy perdiendo?

Gracias de antemano por su tiempo!

Respuesta

2

no está importando su códec - está importando los codecs grails predeterminados. Solo necesita hacer que la importación para el códec en la prueba coincida con la ruta exacta del paquete donde vive el códec. Si está utilizando un IDE, intente importar el códec ...

+0

Gracias hvgotcodes. Entonces, ¿crearía un directorio de hipódromo en grails-app/utils y agregaría "package racetrack" al comienzo de mi códec? Todavía no tengo un IDE instalado, solo uso un editor de texto por el momento. – BenjaminDWest

+1

@benjamindwest, sí, tendría que crear la estructura del paquete manualmente. algo así como com/racetrack/security/codecs en la aplicación grails-app/utils preexistente. Entonces el paquete es com.racetrack.security.codecs, e importaría com.racetrack.security.codecs.SHACodec – hvgotcodes

+0

Muchas gracias. Esto resolvió mi problema. – BenjaminDWest

1

Utilice el método loadCodec de GrailsUnitTestCase. Es muy sencillo. Vea el ejemplo abajo:

import grails.test.* 
import org.codehaus.groovy.grails.plugins.codecs.HTMLCodec 

class SomeTests extends GrailsUnitTestCase { 
    protected void setUp() { 
     super.setUp() 
     loadCodec(HTMLCodec) 
    } 

    protected void tearDown() { 
     super.tearDown() 
    } 

    void testSomething() { 
     assertEquals "&lt;p&gt;Hello World&lt;/p&gt;", "<p>Hello World</p>".encodeAsHTML() 
    } 
} 
0

La respuesta de @hvgotcodes es correcto, pero también hay que añadir la carpeta/utils griales aplicación a la ruta de construcción Java antes de los trabajos de importación (al menos eso es lo que necesitaba hacer con SpringSource Eclipse IDE).

Cuestiones relacionadas