【问题标题】:How to check if an Exception is thrown by a method with xUnit and FsCheck in F#如何检查 F# 中使用 xUnit 和 FsCheck 的方法是否引发了异常
【发布时间】:2016-10-14 18:06:48
【问题描述】:

我在 C# 中使用 xUnit 和 FsCheck 在 F# 中编写测试进行 Diamond Kata,并且在尝试检查用户输入无效时是否引发异常时遇到了一些麻烦(任何字符这不是没有任何变音符号的字母)。下面是代码现在的样子:

正在测试的方法:

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)

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

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

【问题讨论】:

  • 请发布您收到的整个测试失败消息。另外,请格式化代码,以便不需要滚动。
  • 我的猜测是 FsCheck 发现伪造该属性很容易。有许多 char 值超出此处给出的范围,例如üø。根据Char.IsLetter,这些仍然是字母。
  • 你知道你现在正在测试一个 Char.IsLetter 吗?
  • @FoggyFinder 我认为这不公平。测试的是前提条件是否正确实现,如果我理解正确,则不是。
  • 尝试取消引用和/或观看 Mark 在 shareasale.com/… 的 F# 课程中的单元测试中向您展示 - 与 xUnit 的 .Assert 语言一起工作得更好(xUnit 本身很棒,只是断言是最好的替换)

标签: c# unit-testing f# xunit fscheck


【解决方案1】:

我认为问题在于 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

【讨论】:

  • 属性没有返回一个布尔值;他们也可以返回unitProperty。为了返回unit,将Assert.Throws 的结果传递给ignore 应该就足够了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-04
  • 1970-01-01
  • 1970-01-01
  • 2010-11-18
  • 1970-01-01
  • 1970-01-01
  • 2013-02-05
相关资源
最近更新 更多