Grails 1.3.5 тестовый нулевой объект команды контроллера - PullRequest
1 голос
/ 03 ноября 2010

Прямо со страницы 104 «Полного руководства по Граалям (второе издание)»:

void testLoginUserNotFound() {
    mockRequest.method = "POST"
    mockDomain(User)
    MockUtils.prepareForConstraintsTests(LoginCommand)
    def cmd = new LoginCommand(login:"fred", password:"letmein")

    cmd.validate()
    controller.login(cmd)

    assertTrue cmd.hasErrors()
    assertEquals "user.not.found", cmd.errors.login
    assertEquals "/store/index", renderArgs.view
}

Когда этот тест выполняется, он завершается с:

junit.framework.AssertionFailedError: junit.framework.AssertionFailedError: null

... который я отследил до того, что ссылка "cmd" была нулевой в этой точке. Перед вызовом действия controller.login, cmd действителен и заполнен, после этого он равен нулю.

Как проверить объекты команд?

Ответы [ 2 ]

0 голосов
/ 19 ноября 2011

Я использую этот метод в модульных тестах контроллера, чтобы добавить дополнительные параметры для объектов команд:

  private def invoke(String action) {
    def types = controller."$action".parameterTypes
    if (types && types.length == 1) {
      Class cmdClass = types[0]
      mockCommandObject(cmdClass)
      def cmd = cmdClass.newInstance()
      controller.params.each{ key, value ->
        try{ cmd."$key" = value } catch(MissingPropertyException ex){}
      }
      cmd.validate()
      controller."$action"(cmd)
    } else {
      controller."$action"()
    }
  }

Тест выглядит следующим образом:

    setup:
    controller.params.contractNum = "invalid"


    when:
    invoke "lookup"
0 голосов
/ 03 ноября 2010

cmd не null;однако assertTrue выдает AssertionFailedError с сообщением null.Либо укажите сообщение по умолчанию (assertTrue "default message", cmd.hasErrors()), либо просто укажите assert cmd.hasErrors().

Итак, давайте посмотрим, почему cmd.hasErrors() возвращает false.- Это потому, что пользовательский валидатор не возвращает false, а вместо этого некоторую строку, которая оценивается как true в соответствии с «Groovy Truth».(Там, похоже, API Grails изменился после публикации книги.)

В классе LoginCommand измените

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

на

login blank:false, validator:{ val, cmd ->
    if(!cmd.user)
        return false
}

Тогда код ошибки будет «LoginCommand.login.validator».
Если вам нужен собственный код ошибки, вы можете добавить объект ошибки самостоятельно (без возврата чего-либо), например так:1028 *

login blank:false, validator:{ val, cmd ->
    if(!cmd.user)
        cmd.errors.rejectValue('login', 'user.not.found')
}

PS: Вы не должны использовать класс MockUtils напрямую, а вместо этого extend GrailsUnitTest.Кроме того, MockUtils.prepareForConstraintsTests(Class) устарела;кроме того, он не подходит для командных объектов.- Вместо этого используйте метод mockForConstraintsTests(Class), унаследованный от GrailsUnitTest.

...