2010-11-03 1 views
1

Straight со страницы 104 "Полное руководство по Grails (второе издание)":Grails 1.3.5 контроллер команды тестирования обнуляет объект

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 действителен и заполняется, а затем он равен нулю.

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

+1

[-1] Я был прав в части (* * cmd не является нулевым **) и частично неправильным в других частях. - Тем не менее, я определил, загрузил и исправил образцы, чтобы они ** работали ** в практических блочных тестах. - Я ожидал некоторого участия и результирующего ответа. - Вопрос заброшен. – robbbert

ответ

0

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".
Если вам нужен пользовательский код ошибки, вы можете add an error object самостоятельно (без возвращения ничего), например, так:

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

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

0

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

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"