为什么我的 F# 单元测试失败时缺少 Unquote 的输出?

Why is the output from Unquote missing in my F# unit test failures?

我有一个用 F# 编写的单元测试,它使用 Unquote 库来执行断言,如下所示:

module Iccm

open System
open NUnit.Framework
open Swensen.Unquote

[<TestCase("0000000000000000000000000546314", "http://...er.aspx?FolderID=0000000000000000000000000546314")>]
[<TestCase("0000000000000000000000000535126", "http://...er.aspx?FolderID=0000000000000000000000000535126")>]
[<TestCase("0000000000000000000000000545845", "http://...er.aspx?FolderID=0000000000000000000000000545845")>]
[<TestCase("0000000000000000000000000364684", "http://...er.aspx?FolderID=0000000000000000000000000364684")>]
let ``callLink returns complete Uri with given eFolderId embedded`` 
    eFolderId expectedUri =
    test <@ Iccm.callLink eFolderId = expectedUri @>

到目前为止非常好。我让测试失败,所以我可以看到 Unquote 如何逐步揭示引用表达式的评估,但我没有在我的测试运行器控制台中获得 unquote 报告

C:\TFS\SANDBOX_2456764.0\PrototypeWorkspace\IccmToTfs\src\IccmToTfs.Console.Tests\bin\Debug>"C:\Program Files (x86)\NUnit 2.6.4\bin\nunit-console-x86.exe" IccmToTfs.
Console.Tests.dll
NUnit-Console version 2.6.4.14350
Copyright (C) 2002-2012 Charlie Poole.
Copyright (C) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov.
Copyright (C) 2000-2002 Philip Craig.
All Rights Reserved.

Runtime Environment -
   OS Version: Microsoft Windows NT 6.1.7601 Service Pack 1
  CLR Version: 2.0.50727.5485 ( Net 3.5 )

ProcessModel: Default    DomainUsage: Single
Execution Runtime: net-3.5
.F.F.F.F.......
Tests run: 11, Errors: 4, Failures: 0, Inconclusive: 0, Time: 0.319073211837137 seconds
  Not run: 0, Invalid: 0, Ignored: 0, Skipped: 0

Errors and Failures:
1) Test Error : Iccm.callLink returns complete Uri with given eFolderId embedded("0000000000000000000000000545845","http://usas25/esdSSO/eExternalForm.asp?service=IC
CM%20e-Service%20Desk&redirect=http://usas25/esd/eFolder.aspx?FolderID=0000000000000000000000000545845%2526client=external%2526Service=ICCM+e-Service+Desk")
   System.ArgumentException : Object of type 'System.String' cannot be converted to type 'System.Uri'.
   at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
   at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
   at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
   at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at NUnit.Core.Reflect.InvokeMethod(MethodInfo method, Object fixture, Object[] args)
   at NUnit.Core.TestMethod.RunTestMethod()
   at NUnit.Core.TestMethod.RunTestCase(TestResult testResult)

2) Test Error : Iccm.callLink returns complete Uri with given eFolderId embedded("0000000000000000000000000546314","http://usas25/esdSSO/eExternalForm.asp?service=IC
CM%20e-Service%20Desk&redirect=http://usas25/esd/eFolder.aspx?FolderID=0000000000000000000000000546314%2526client=external%2526Service=ICCM+e-Service+Desk")
   System.ArgumentException : Object of type 'System.String' cannot be converted to type 'System.Uri'.
   at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
   at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
   at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
   at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at NUnit.Core.Reflect.InvokeMethod(MethodInfo method, Object fixture, Object[] args)
   at NUnit.Core.TestMethod.RunTestMethod()
   at NUnit.Core.TestMethod.RunTestCase(TestResult testResult)

我在命令行上尝试了 NUnit,在 Visual Studio 2013 年尝试了 ReSharper,但似乎都不知道如何读取 Unquote 输出。有谁知道为什么?是否有我必须使用的不同测试运行程序才能使 Unquote 正常工作?

更新:

另一个测试用例失败并很好地演示了 Unquote 输出:

[<TestCase(3s, "03/02/2015", 3150202)>]
let ``callPriority returns expected integer given a priority and date``
    priority dateString expectedInteger =
    let date = DateTime.Parse(dateString)
    test <@ Iccm.callPriority priority date = expectedInteger @>

Unquote 的输出:

Iccm.callPriority 3s 3/2/2015 12:00:00 AM = 3150202
3150302 = 3150202
false

如果您阅读错误消息,包括调用堆栈,您会发现异常是由 NUnit 测试抛出的 运行ner。

测试主体永远不会执行,因为:

Object of type 'System.String' cannot be converted to type 'System.Uri'.

[TestCase] 属性中的值是 string 值,但看起来 F# 编译器已将参数之一推断为 Uri 个实例。

我的猜测是 eFolderId 参数被推断为 Uri 值,因为它被用作函数参数。不幸的是,我们不知道 Iccm.callLink 函数的类型是什么,所以这只是一个猜测。

将一个或两个参数(eFolderIdexpectedUri)静态类型化为 Uri,以及 [TestCase] 值的 运行 时间类型作为 string 值,.NET 运行time 将尝试将 string 转换为 Uri.

没有从 stringUri 的隐式转换,这就是抛出异常的原因。

此时甚至不涉及 Unquote。