Grails как выполнить юнит-тест на исключения - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь проверить, что срок действия учетной записи истек, исключение.

def authfail() {
    String msg = ''
    def exception = session[WebAttributes.AUTHENTICATION_EXCEPTION]

//        println("print exception: ${exception} | ${session} | ${springSecurityService.getCurrentUser()}")
    if (exception) {
        if (exception instanceof AccountExpiredException) {
            msg = message(code: 'springSecurity.errors.login.expired')
        }
        else if (exception instanceof CredentialsExpiredException) {
            msg = message(code: 'springSecurity.errors.login.passwordExpired')
        }
        else if (exception instanceof DisabledException) {
            msg = message(code: 'springSecurity.errors.login.disabled')
        }
        else {
            msg = message(code: 'springSecurity.errors.login.fail')
        }
    }

    if (springSecurityService.isAjax(request)) {
        render([error: msg] as JSON)
    }
    else {
        flash.message = msg
        redirect action: 'auth', params: params
    }
}

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

void "test authFail"() {

when:
    session."${WebAttributes.AUTHENTICATION_EXCEPTION}" = new AccountExpiredException( 'This account has expired' )
    def logexp = controller.authfail()
then:
    logexp == 'springSecurity.errors.login.expired'
when:
    session."${WebAttributes.AUTHENTICATION_EXCEPTION}" = new CredentialsExpiredException( 'This credentials have expired' )
    def passexp = controller.authfail()
then:
    passexp == 'springSecurity.errors.login.passwordExpired'
when:
    session."${WebAttributes.AUTHENTICATION_EXCEPTION}" = new DisabledException( 'The account is disabled' )
    def logdis = controller.authfail()
then:
    logdis == 'springSecurity.errors.login.disabled'
when:
    session."${WebAttributes.AUTHENTICATION_EXCEPTION}" = new UnsupportedOperationException( 'Sorry, we were not able to find a user with that username and password.' )
    def logfail = controller.authfail()
then:
    logfail == 'springSecurity.errors.login.fail'
when:
    controller.authfail()
then:
    1 * springSecurityService.isAjax( _ ) >> true
    controller.response.json == [error :'springSecurity.errors.login.fail']

    }
}

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Хотя это не Grails, это SpringBoot 2.0.

Если failHandler выставлен как бин, можно просто шпионить за ним.

@SpyBean
AuthenticationFailureHandler failureHandler;

и просто убедитесь, что сгенерировано исключение

Mockito.verify(failureHandler).onAuthenticationFailure(
    any(),
    any(),
    any(AccountExpiredException.class)
);

Простой тест может выглядеть так:

@Test
public void accountExpired() throws Exception {
    doReturn(user
        .username("expired")
        .accountExpired(true)
        .build()
    ).when(userDetailsService).loadUserByUsername(any(String.class));
    mvc.perform(
        MockMvcRequestBuilders.post("/login")
            .param("username", "expired")
            .param("password", "password")
    )
        .andExpect(status().is4xxClientError())
        .andExpect(unauthenticated())
    ;
    Mockito.verify(failureHandler).onAuthenticationFailure(
        any(),
        any(),
        any(AccountExpiredException.class)
    );
}

Все образцы в https://github.com/fhanik/spring-security-community/

0 голосов
/ 08 января 2019

Следующие тесты проверят большую часть вашего метода:

import grails.plugin.springsecurity.SpringSecurityService
import grails.test.mixin.TestFor
import org.springframework.security.authentication.AccountExpiredException
import org.springframework.security.authentication.CredentialsExpiredException
import org.springframework.security.authentication.DisabledException
import org.springframework.security.web.WebAttributes
import spock.lang.Specification

@TestFor(YourController)
class YourControllerSpec extends Specification {

def springSecurityService = Mock( SpringSecurityService )

void setup() {
    controller.springSecurityService = springSecurityService
}

void "test authFail"() {
    given:
        session."${WebAttributes.AUTHENTICATION_EXCEPTION}" = new AccountExpiredException( 'This account has expired' )
    when:
        controller.authfail()
    then:
        flash.message == 'springSecurity.errors.login.expired'
    when:
        session."${WebAttributes.AUTHENTICATION_EXCEPTION}" = new CredentialsExpiredException( 'This credentials have expired' )
        controller.authfail()
    then:
        flash.message == 'springSecurity.errors.login.passwordExpired'
    when:
        session."${WebAttributes.AUTHENTICATION_EXCEPTION}" = new DisabledException( 'The account is disabled' )
        controller.authfail()
    then:
        flash.message == 'springSecurity.errors.login.disabled'
    when:
        session."${WebAttributes.AUTHENTICATION_EXCEPTION}" = new UnsupportedOperationException( 'Bad stuff' )
        controller.authfail()
    then:
        flash.message == 'springSecurity.errors.login.fail'
    when:
        controller.authfail()
    then:
        1 * springSecurityService.isAjax( _ ) >> true
        response.json == [error :'springSecurity.errors.login.fail']
}
}

Сессия - это просто карта, к которой мы добавляем ключ строковой константы и значение исключения. Для всех тестов, за исключением последнего, мы переходим к вашему последнему блоку else, в последнем тесте мы возвращаем true для `isAjax '.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...