Выкинь исключение из метода имитации грааля - PullRequest
5 голосов
/ 02 марта 2012

На тестовом модуле контроллера Grails (точнее, на Споке ControllerSpec) я хотел бы проверить поведение тестируемого метода, когда соавтор выдает исключение.

Я используюУтилита mockFor (либо из Spock's UnitSpec, либо из GrailsUnitTestMixin Grails) задает мои требования к такому методу исключения в тесте, например:

@TestFor(TestController)
class TestControllerSpec extends Specification {

    def "throwing and exception from a mock method should make the test fail"() {
        setup:
        def serviceMock = mockFor(TestService)
        serviceMock.demand.exceptionThrowingMethod() { throw new Exception() }
        controller.testService = serviceMock.createMock()

        when:
        controller.triggerException()

        then:
        thrown(Exception)
    }
}

Итак, внутри triggerException я вызываю exceptionThrowingMethod,как это:

class TestController {

    def testService

    def triggerException() {
        testService.exceptionThrowingMethod()
    }
}

Но тест терпит неудачу, как:

Ожидаемое исключение java.lang.Exception, но исключение не было выдано

Я отладил исключение, и исключение не было сгенерировано beign, вызов exceptionThrowingMethod неожиданно возвращает Закрытие.Не берите в голову добавление объявления throws к сигнатуре метода, тоже не сработает.

Я думал, что это было связано со Споком, но я попробовал подобный тест, используя только миксины теста Grails, и получил тот же результат.Это была моя попытка:

@TestFor(TestController)
class TestControllerTests {

    void testException() {
        def serviceMock = mockFor(TestService)
        serviceMock.demand.exceptionThrowingMethod() { throw new Exception() }
        controller.testService = serviceMock.createMock()

        shouldFail(Exception) {
            controller.triggerException()
        }
    }
}

Считаете ли вы что-то неправильным в моем коде?

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

Мне также кажется подозрительным, что я не нахожу ничего, связанного с поиском в Google, поэтому, возможно, я пытаюсь сделать что-то не так в отношении тестирования.

Неэто частый случай при тестировании?Вы высмеиваете детерминированное поведение какого-либо метода в конкретном сценарии, а затем тестируете ожидаемое поведение тестируемого метода при возникновении такого сценария.Создание исключения выглядело для меня как правильный сценарий.

1 Ответ

9 голосов
/ 02 марта 2012

Кажется, что создание demand замыкания niladic (то есть без неявного it аргумента с явным ->) делает трюк :

serviceMock.demand.exceptionThrowingMethod {-> throw new Exception() }

Обновление : вы также можете использовать нативный класс Groovy MockFor, который, по-видимому, не требует этого странного замыкания:

@TestFor(TestController)
class TestControllerTests {

    void testException() {
        def mock = new MockFor(TestService)
        mock.demand.exceptionThrowingMethod { throw new Exception() }
        controller.testService = mock.proxyInstance()

        shouldFail { controller.triggerException() }
        mock.verify(controller.testService)
    }
}

Обратите внимание, что когда не используется mock.use, mock.verify необходимо использовать для проверки ложных ограничений (т. Е. Чтобы exceptionThrowingMethod был вызван один раз).

...