2009-11-09 1 views
5

Я пытаюсь протестировать контроллер , у которого есть объект Command с привязкой данных.Grails: Как вы тестируете объект команды с помощью введенной в нее службы

Командный объект имеет введенную в него услугу.

Но когда я пытаюсь проверить команду Объект нагнетаемый метод обслуживания не встречается, как он никогда не «впрыскивается»

Есть ли способ издеваться услугу внутри объекта команды?

Метод испытания

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 
} 

Метод GetUser() из UserService не найден

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

код

Метод Логин контроллера вызывается,

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') 
    } 
} 

У объекта Command есть «userService», введенный в него.

Валидатор называет это UserService найти пользователя

class LoginCommand { 

    def userService 

    String login 
    String password 

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

userService.getUser() выглядит следующим образом.

class UserService { 

    boolean transactional = true 

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

    } 
} 

ответ

11

Эксплуатационная инъекция осуществляется с использованием пружинного автоповорота по названию. (Grep the Grails исходное дерево для autowire, чтобы найти хороший фрагмент кода, который вы можете использовать, чтобы получить его для автоматического тестирования ваших контроллеров для вас в тестах интеграции.) Это работает только в тестах интеграции, где есть контекст приложения Spring, в котором есть компоненты, которые могут быть введены.

В модульных тестах вы должны сделать это сами, так как нет весны, окружающих ваши вещи. Это может быть болью, но дает вам некоторые преимущества:

1) Легко вводить макеты версий услуг, например, с помощью Expando - для более детального описания поведения взаимодействующих служб вашего диспетчера и для позволяют вам тестировать только логику контроллера, а не контроллер и сервис вместе. (Конечно, вы также можете сделать последнее в модульном тесте, но у вас есть выбор, как его подключить.)

2) Это заставляет вас четко указывать зависимости вашего контроллера - если вы зависите от это ваши тесты покажут. Это делает их лучшей спецификацией поведения вашего контроллера.

3) Вы можете высмеять только части внешних соавторов, от которых зависит ваш контроллер. Это помогает вашим испытаниям быть менее хрупкими - менее вероятно, придется менять, когда что-то меняется.

Короткий ответ: вашему методу тестирования нужна линия cmd.userService = userService.

+0

Спасибо, это сработало лакомство , и теперь я понимаю больше – Daxon

8

То, что говорит Джон, находится на отметке.Одним из примеров могут быть:

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 

Вы можете поиск других способов фиктивных объектов в http://groovy.codehaus.org/Groovy+Mocks