пятница, 11 апреля 2008 г.

grails: unit testing

Пришлов время пописать юнит тесты. Юнит тестировал я один из методов сервиса, который проверяет может ли пользователь видеть урл или нет.
Метод вот такой:

class SecurityService {
static digestAlgo = "MD5"


boolean checkAccess(def acc, def controller, def action) {
def attachedAcc = Account.get(acc.id)
def checkingUrl = controller + "/" + action
def realRes = false

log.debug "let's check it"
log.debug "attachedAcc : ${attachedAcc}"
log.debug "checkingUrl : ${checkingUrl}"

if(attachedAcc) {
attachedAcc.roles.urls*.find { requestmap ->
if(checkingUrl =~ requestmap.url) {
realRes = true
return true
}
}
}

return realRes
}
...
}


Так как я захотел создать именно юнит тест, то все инжекты из grails необходимо было проэмулировать. А это следующее:
Account.get
объект log
attachedAcc.roles.urls - т.е. свойства roles и urls.
И здесь на выручку приходит динамеческая природа groovy, которая позволяет всё необходимое добавить к классам прямо в run-time.
И так:
1. создаём список аккаунтов, назначем аккаунтам роли, ролям паттерны доступных урлов

def adminRole = new Role()
adminRole['urls'] = [
[url: ".*"],
]
def adminAccount = new Account(username : 'admin')
adminAccount['roles'] = [adminRole]

def oneControllerAllRole = new Role()
oneControllerAllRole['urls'] = [
[url: "one/.*"],
]

def restrictedRole = new Role()
restrictedRole['urls'] = [
[url: "two/three"],
[url: "four/five"]
]

def account1 = new Account(username : 'oneAll')
account1['roles'] = [oneControllerAllRole]
def account2 = new Account(username : 'restricted')
account2['roles'] = [restrictedRole]
def account3 = new Account(username : 'oneAllAndRestricted')
account3['roles'] = [oneControllerAllRole, restrictedRole]

def accounts = [
(new Long(1)) : adminAccount,
(new Long(2)) : account1,
(new Long(3)) : account2,
(new Long(4)) : account3
]

2. Добавляем к Account метод get()

Account.metaClass.static.get = { Long id ->
return accounts[(id)]
}

3. Добавляем к сервису объект log. Ну и конечно же надо создать сам сервис.

def sol = new SOL()
SecurityService.metaClass.getLog = { ->
return sol
}
securityService = new SecurityService()

здесь SOL - простейщий класс реализующий метод debug()

Собственно всё, среда готова, можно тестировать.

Комментариев нет: