2016-10-14 12 views
2

Я делаю Diamond Kata в C# с тестами, написанными в F #, с помощью xUnit и FsCheck, и у меня возникают некоторые проблемы при попытке проверить если исключение вызывается в случае недопустимого ввода пользователем (любой символ, который не является буквой алфавита без каких-либо диакритических знаков). Вот как выглядит код прямо сейчас:Как проверить, выбрано ли исключение методом xUnit и FsCheck в F #

Метод тестируется:

public static string Make(char letter) 
{ 
    if (!Regex.IsMatch(letter.ToString(), @"[a-zA-Z]")) 
    { 
     throw new InvalidOperationException(); 
    } 

    // code that makes the diamond 
} 

Тест:

[<Property>] 
let ``Diamond.Make must throw an InvalidOperationException if a character that isn't 
     an alphabet letter without any diacritics is given`` (letter : char) = 
    (not (('A' <= letter && letter <= 'Z') || ('a' <= letter && letter <= 'z'))) ==> lazy 
     (Assert.Throws<InvalidOperationException>(fun() -> Diamond.Make letter |> ignore)) 

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

Вот сообщение дается набор тестов (я намеренно опущено имя тестирования и трассировки стека):

Test Outcome: Failed 
Test Duration: 0:00:00,066 
Result Message: 
FsCheck.Xunit.PropertyFailedException : 
Falsifiable, after 1 test (0 shrinks) (StdGen (1154779780,296216747)): 
Original: 
')' 
---- Assert.Throws() Failure 
Expected: typeof(System.InvalidOperationException) 
Actual: (No exception was thrown) 

Хотя набор тестов говорит, что для значения ')' не отбрасывается исключением, я сделал ручной тест с ним, и ожидаемое исключение действительно было брошено.

Как я могу убедиться, что Исключение попало в тест?

+3

Пожалуйста, разместите сообщение об ошибке полного тестирования, которое вы получаете. Кроме того, пожалуйста, отформатируйте код, чтобы прокрутка не нужна. –

+3

Мое предположение заключается в том, что FsCheck с легкостью фальсифицирует это свойство. Существует множество значений 'char', которые выходят за пределы заданного здесь диапазона, например. 'ü' и' ø'. Это все еще буквы в соответствии с 'Char.IsLetter'. –

+1

Вы понимаете, что сейчас тестируете Char.IsLetter? –

ответ

4

Я думаю, проблема в том, что Assert.Throws возвращает исключение данного типа, если это происходит. Просто игнорируя возвращаемое значение Assert.Throws должно помочь вам.

let test (letter : char) = 
    (not (('A' <= letter && letter <= 'Z') || ('a' <= letter && letter <= 'z'))) ==> 

    lazy 
     Assert.Throws<InvalidOperationException>(fun() -> Diamond.Make letter |> ignore) 
     |> ignore 
+0

Свойства не имеют * have *, чтобы возвращать логическое значение; они также могут возвращать 'unit', или' Property'. Чтобы возвратить 'unit', для того, чтобы получить результат' Assert.Throws' в 'ignore', должно быть достаточно. –

+0

@MarkSeeman Вы правы. Я отредактирую ответ. –

+0

Таким образом, это сработало. Благодаря! –