如何检查 F# 中带有 xUnit 和 FsCheck 的方法是否抛出异常

Lio*_*eto 2 c# f# unit-testing xunit fscheck

我正在 C# 中执行 Diamond Kata,并使用 xUnit 和 FsCheck 在 F# 中编写测试,并且在尝试检查在用户输入无效的情况下是否抛出异常时遇到了一些问题(任何不是的字符) t 一个没有任何变音符号的字母)。下面是代码的样子:

正在测试的方法:

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

    // code that makes the diamond
}
Run Code Online (Sandbox Code Playgroud)

考试:

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

    // code that makes the diamond
}
Run Code Online (Sandbox Code Playgroud)

我的方法的问题是测试表明没有抛出异常,但是当我使用测试套件显示的输入运行应用程序时,会引发异常。

这是测试套件给出的消息(我故意省略了测试名称和堆栈跟踪):

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)
Run Code Online (Sandbox Code Playgroud)

虽然测试套件说对于该值')'没有抛出异常,但我对其进行了手动测试,确实抛出了预期的异常。

如何确保异常被测试捕获?

Ant*_*nen 5

我认为问题在于 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
Run Code Online (Sandbox Code Playgroud)