Pregunta

Estoy tratando de probar un controlador que tiene un objeto de comando con el enlace de datos.

El objeto de comando tiene un servicio inyectado en ella.

Pero cuando intento probar el comando objeto el método de servicio inyectada nunca se encuentra, ya que nunca se "inyecta"

¿Hay una manera de burlarse de un servicio dentro de un objeto de comando?

Método de ensayo

void testLoginPasswordInvalid() {
    mockRequest.method = 'POST'
    mockDomain(User, [new User(login:"freddy", password:"realpassword")])
    mockLogging(UserService) // userService mocked
    MockUtils.prepareForConstraintsTests(LoginCommand)

    def userService = new UserService()
    def user = userService.getUser("freddy")//Gets called and returns the mockDomain
    assert userService.getUser("freddy")//Passes

    def cmd = new LoginCommand(login:"freddy", password:"letmein")
    cmd.validate() // Fails (userService is nevr injected)
    controller.login(cmd)
    assertTrue cmd.hasErrors()
    assertEquals "user.password.invalid", cmd.errors.password
    assertEquals "/store/index", renderArgs.view
}

No se encuentra el método getUser () de la UserService

Cannot invoke method getUser() on null object
java.lang.NullPointerException: Cannot invoke method getUser() on null object

Código

El método de inicio de sesión del controlador que se llama,

def login = { LoginCommand cmd ->
  if(request.method == 'POST') {
     if(!cmd.hasErrors()){
       session.user = cmd.getUser()
       redirect(controller:'store')
     }
     else{
       render(view:'/store/index', model:[loginCmd:cmd])
     }
  }else{

    render(view:'/store/index')
  }
}

El objeto de comando tiene un "UserService" inyectado en él.

El validador llama a esto UserService para encontrar un usuario

 class LoginCommand {

    def userService

    String login
    String password

    static constraints = {
      login blank:false, validator:{ val, cmd ->
          if(!cmd.userService.getUser()){
             return "user.not.found"
          }
      }
 }

El userService.getUser () se parece a esto.

class UserService {

    boolean transactional = true

    User getUser(String login) {
        return User.findByLogin(login)

    }
}
¿Fue útil?

Solución

Servicio de inyección se realiza utilizando Spring Autowire por nombre. (GREP el árbol de fuentes Grails para autowire para encontrar un fragmento de código agradable que puede utilizar para conseguir que Autowire sus controladores para que en las pruebas de integración.) Esto sólo funciona en las pruebas de integración, donde hay un contexto de aplicación de primavera en torno a que tiene los granos que se puede inyectar.

En las pruebas de unidad, que tiene que hacer esto por sí mismo ya que no hay primavera-tierra que rodea su materia. Esto puede ser un dolor, pero le da algunas ventajas:

1) Es fácil de inyectar versiones simuladas de servicios - por ejemplo, usando un Expando - con el fin de especificar más de cerca el comportamiento de los servicios de colaboración de su controlador, y permitirá poner a prueba únicamente la lógica del controlador en lugar del controlador y mantienen juntas. (Por supuesto que puede hacer esto último en una prueba de unidad, así, pero usted tiene la opción de cómo cablear.)

2) Se obliga a ser explícito acerca de las dependencias de su controlador - si depende de él, sus pruebas mostrarán la misma. Esto los convierte en una mejor especificación del comportamiento de su controlador.

3) Se puede burlarse sólo las piezas de colaboradores externos su controlador depende. Esto ayuda a que las pruebas sean menos frágiles -. Menos probable que tenga que cambiar cuando cambian las cosas

Respuesta corta: el método de prueba necesita una línea cmd.userService = userService

.

Otros consejos

Lo que Juan dice es en la marca. Un ejemplo podría ser:

def mockUsers = [new User(login:"freddy", password:"realpassword")]
mockDomain(User, mockUsers)

def userService = [getUser:{String login -> mockUsers[0]}] as UserService

def cmd = new LoginCommand (/*arguments*/)
cmd.userService = userService

Se puede buscar otras formas de objetos simulados en http://groovy.codehaus.org/Groovy+Mocks

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top