Как правильно тестировать исключения с помощью FsUnit

Я пытаюсь понять, как правильно тестировать исключения с помощью FsUnit. Официальная документация гласит, что для проверки исключений я должен исправить что-то вроде этого:

(fun () -> failwith "BOOM!" |> ignore) |> should throw typeof<System.Exception>

Но если я не отмечу свой тестовый метод атрибутом [<ExpectedException>], он всегда будет терпеть неудачу. Звучит разумно, потому что если мы хотим протестировать исключения, мы должны добавить такой атрибут в C# + NUnit.

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

Некоторые фрагменты: Мой LogicModule.fs

exception EmptyStringException of string

let getNumber str =
    if str = "" then raise (EmptyStringException("Can not extract number from empty string"))
    else int str

Мой LogicModuleTest.fs

[<Test>]
[<ExpectedException>]
let``check exception``()=
    (getNumber "") |> should throw typeof<LogicModule.EmptyStringException>

person fxdxpz    schedule 28.04.2013    source источник
comment
К сведению: с Unquote, code.google.com/p/unquote, вы бы утверждали, что getNumber "" в вашем последнем примере вызывает ожидаемое исключение, например raises<LogicModule.EmptyStringException> <@ getNumber "" @>   -  person Stephen Swensen    schedule 28.04.2013


Ответы (2)


Ответ найден. Чтобы проверить, было ли выброшено исключение, я должен обернуть вызов функции в следующем стиле:

(fun () -> getNumber "" |> ignore) |> should throw typeof<LogicModule.EmptyStringException>

потому что под #fsunit используется ограничение Throws NUnit http://www.nunit.org/index.php?p=throwsConstraint&r=2.5 … который принимает делегата void, raise возвращает 'a

person fxdxpz    schedule 28.04.2013
comment
Хороший ответ - я не думаю, что вам нужен атрибут ExpectedException. - person TrueWill; 09.06.2013
comment
Обратите внимание, что возврат единицы измерения из лямбды (т. е. завершение определения fun с помощью '|› ignore') является обязательным. - person James Hugard; 09.01.2016

Если вы хотите проверить, вызывается ли определенный тип исключения каким-либо кодом, вы можете добавить тип исключения в атрибут [<ExpectedException>] следующим образом:

[<Test; ExpectedException(typeof<LogicModule.EmptyStringException>)>]
let``check exception`` () : unit =
    (getNumber "")
    |> ignore

Дополнительная документация доступна на сайте NUnit: http://www.nunit.org/index.php?p=exception&r=2.6.2

person Jack P.    schedule 28.04.2013
comment
Спасибо за ответ, но мне не нравится идея добавления какого-то дополнительного атрибута, потому что это выглядит не очень хорошо, когда вы используете FsUnit. - person fxdxpz; 28.04.2013