Grails: поведение list.contains в тесте кода против интеграции

Представьте, что есть форма для массового обновления группы логинов и их статусов; Используемая логика заключается в наличии скрытого поля, которое отслеживает все возможные идентификаторы и группу… например, радио-btns. позже через сервис, активируя все проверенные идентификаторы в нашем списке и деактивируя остальные:

def enabledLogins = toList(params.enabledLogins)
def allLoginIds = params.allLoginIds.toString().split(',')
loginService.updateLoginStatus(allLoginIds,enabledLogins)

вот определение сервиса

def updateLoginStatus(String[] allLoginIds, List<Long> enabledLoginIds) {
    for (item in allLoginIds) {
        def login = Login.get(item.toLong())
        if (login) {
            login.enabled = enabledLoginIds.contains(item.toLong()) ? true : false
            login.save()
            if (login.hasErrors()) {
                login.errors.each { log.error(it) }
            }
        }
    }
}

А вот и интеграционный тест:

def testUpdateLoginStatus() {
    def id1 = createLogin().id
    def id2 = createLogin().id

    String[] allLoginIds = [id1 as String, id2 as String]
    List<Long> enabledLoginIds = [id1]

    loginService.updateLoginStatus(allLoginIds, enabledLoginIds)

    def login1 = Login.get(id1)
    def login2 = Login.get(id2)
    assertTrue login1.enabled
    assertFalse login2.enabled
}
Login createLogin() {
    def now = System.currentTimeMillis()

    def email = "int-test-" + now + "@somewhere.com"
    def password = "Pwd" + now + "pwD"

    def login = new Login(username: email, password: password, firstName: "Integration", lastName: "Test")
    login.save(flush: true)
    assertNotNull login.id

    return login
}

Теперь вот проблема:
Приведенный выше код просто проходит тест интеграции, но не работает на практике, если я не вывожу toLong из

 enabledLoginIds.contains(item.toLong()) 
который в таком случае не проходит интеграционный тест... так что тип где-то как-то не так... но я не вижу его
Спасибо
Ps: Граальс 1.3.7

1 ответ

Решение

Все параметры выглядят как строки, поэтому код в вашем контроллере:

def enabledLogins = toList(params.enabledLogins)

Который создает список строк. Вот почему, если вы запустите приложение.toLong(), оно будет работать. Потому что тогда это делает:

["1", "2"].contains("1")

Вместо вашей текущей реализации с.toLong, в результате чего:

["1", "2"].contains(1)

Есть несколько вещей, которые я вижу здесь:

1) Помните, что дженерики - это только время компиляции (поэтому в целом они бесполезны) Так что, хотя у вас есть параметр (... , List<Long> enabledLoginIds) в подписи вашего метода. Во время выполнения нет гарантии, что это будет список длинных.

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

Другие вопросы по тегам