Могу ли я написать тестовый пример с Test.HUnit
, который проверяет, вызывает ли вызов исключение?Тестирование модулей для исключений
Мне все равно, не вызывает ли это ошибки, независимо от того, какое сообщение оно печатает.
Могу ли я написать тестовый пример с Test.HUnit
, который проверяет, вызывает ли вызов исключение?Тестирование модулей для исключений
Мне все равно, не вызывает ли это ошибки, независимо от того, какое сообщение оно печатает.
Это не относится к HUnit, но вы можете написать функцию для проверки кидает ли IO
значение:
λ> :set -XScopedTypeVariables
λ> import Control.Exception
λ> import Data.Functor
λ> import System.Environment
λ> throws io = catch (io $> False) $ \(e :: SomeException) -> pure True
throws :: IO a -> IO Bool
λ> sequence $ throws <$> [ getEnv "HOME", getEnv "whatever", error "a" ]
[False,True,True]
Если с помощью «исключение» вы имеете в виду Exception
и его бросают в некоторых IO
код, то вы можете использовать . Однако, если вы имеете в виду ловить вещи вроде error "Something bad happened"
в чистом коде, вам не повезло. Если вы готовы сделать обработку в IO
, у вас есть больше возможностей:
ghci> import Control.Exception
ghci> catch (error "Eek") (\(ErrorCallWithLocation msg _) -> putStrLn msg)
Eek
Из отчета о Haskell 2010 section 3:
Ошибки во время вычисления выражений, обозначаемые ⊥ («дно »), Неотличимы от программы Haskell от неограниченного доступа.
Вот еще один способ думать об этом: обратите внимание, что в тот момент мы пытаемся оценить значение, которое ⊥ (как error "Help!"
) зависит не от того, когда это значение было создано но только тогда, когда он был первым нужен (поскольку Haskell не является строгим). Механизм, чтобы поймать такую ошибку, затем нарушит ссылочную прозрачность.
Будет ли это работать и для «ошибки»? – cberkay
Да, если вы используете 'error' для создания значений типа' IO'. Я обновил ответ, чтобы включить это. –
Спасибо. Я, вероятно, отсутствует что-то очевидное, но когда я ввожу свой код в repl, я получаю сообщение об ошибке для 'throws io = ...': 'Недопустимая подпись типа: 'SomeException' Подписи типов допускаются только в шаблонах с ScopedTypeVariables' – cberkay