grails: поведение list.contains в коде против интеграционного теста - PullRequest
0 голосов
/ 19 января 2012

Представьте, что существует форма для массового обновления группы логинов и их статусов; используемая логика заключается в наличии скрытого поля, которое отслеживает все возможные идентификаторы, и группы… например, Радио БТНС. позже через сервис, активируя все проверенные идентификаторы в нашем списке и деактивируя остальные:

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: grails 1.3.7

1 Ответ

0 голосов
/ 19 января 2012

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

def enabledLogins = toList(params.enabledLogins)

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

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

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

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

Здесь я вижу пару вещей:

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

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

...