2

我正在 WCF 服务上运行一些单元测试。该服务配置为在故障响应中包含异常详细信息(在我的服务配置文件中包含以下内容)。

<serviceDebug includeExceptionDetailInFaults="true" />

如果测试在服务器上导致未处理的异常,则客户端会收到故障,并带有完全填充的服务器堆栈跟踪。我可以通过调用异常的ToString()方法看到这一点。问题是我尝试过的任何测试运行器(xUnit、Gallio、MSTest)似乎都没有输出。它们似乎只是输出异常的 Message 和 StackTrace 属性。

为了说明我的意思,以下单元测试将输出三个部分:

  • 错误信息
  • 错误堆栈跟踪
  • 标准控制台输出(包含我想要的信息,例如“故障详细信息等于异常详细信息,可能由 IncludeExceptionDetailInFaults=true 创建,其值为:...”

public void Test()
{
    try
    {
        service.CallMethodWhichCausesException();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex); // this outputs the information I would like
       throw;
    }
}

编辑: 但是,我宁愿不要被迫在每个测试中捕获异常并将其写入控制台以确定FaultException对象Detail属性中的内容。

例如,

public void Test()
{
    service.CallMethodWhichCausesException();
}

拥有这些信息将使测试和部署的初始阶段变得不那么痛苦。

我知道我可以将每个单元测试包装在一个通用异常处理程序中,并将异常写入控制台并在我的所有单元测试中重新抛出(如上所述),但这似乎是实现这一目标的一种非常冗长的方式(而且看起来很糟糕)。

有谁知道是否有任何方法可以在发生未处理的异常时包含此信息?有没有我缺少的设置?我的服务配置是否缺乏适当的故障处理?也许我可以为某些单元测试框架编写某种插件/适配器?也许我应该使用不同的单元测试框架!

我的实际设置是通过 Gallio 为开发环境执行的 xUnit 单元测试,但我确实编写了一套单独的“冒烟测试”,我希望能够让我们的工程师通过 xUnit GUI 测试运行器(或Gallio 或其他)以简化最终部署。

谢谢。

亚当

4

3 回答 3

1

我想我已经找到了解决办法。Oleg Sych 已经实现了一个 WCF 行为,它透明地将异常从服务器发送到客户端,在客户端上引发它们,就好像它们已经发生在那里一样。

就像在服务契约(接口)中添加服务行为属性一样简单。

如果决定编写为在单个进程中执行的现有代码应通过 WCF 服务分发,则此方法特别有用。这意味着它可以在不需要对客户端的异常处理进行任何更改的情况下实现(例如,您仍然可以SecurityException在客户端处理 a 而不必FaultException<SecurityException>在移动到更加分布式的设计时处理 a)。

该帖子可以在这里找到:http ://www.olegsych.com/2008/07/simplifying-wcf-using-exceptions-as-faults/

由于我的 WCF 服务混合使用 ws2007HttpBinding 和 basicHttpBinding(用于互操作性),因此我不得不对代码进行一些更改(如上面帖子的评论中所述)。具体来说:

ExceptionMarshallingMessageInspector.AfterReceiveReply

Exception exception = faultDetail as Exception;
if (exception != null)
{
    // NB: Error checking etc. excluded
    // Get the _remoteStackTraceString of the Exception class

    FieldInfo remoteStackTraceString = typeof(Exception).GetField(
        "_remoteStackTraceString",
        BindingFlags.Instance | BindingFlags.NonPublic);

    // Set the InnerException._remoteStackTraceString to the current InnerException.StackTrace
    remoteStackTraceString.SetValue(
        exception,
        exception.StackTrace + Environment.NewLine);

    throw exception;
}

...并且ExceptionMarshallingMessageInspector.ReadFaultDetail 我进行了更改,以便它查找本地名称等于“Detail”(对于 ws2007HttpBinding)或“detail”(对于 basicHttpBinding)的详细信息节点。

我希望这有帮助。

亚当

于 2011-01-12T11:05:52.973 回答
0

控制台输出在“测试结果”窗口中作为一列提供。

于 2011-01-12T04:22:17.663 回答
0

Gallio 默认将控制台输出重定向到其诊断日志。所以你应该直接在测试报告中看到你需要的信息。

例如,在 HTML 报告的详细信息部分中,展开测试树并找到您的测试方法。

Gallio 测试报告中的控制台输出

于 2011-01-12T06:51:28.627 回答