C# 单元测试WCF故障

C# 单元测试WCF故障,c#,wcf,unit-testing,faultexception,wcf-faults,C#,Wcf,Unit Testing,Faultexception,Wcf Faults,对WCF服务的预期故障进行单元测试的最佳方法是什么 我试图对一个WCF服务进行单元测试,该服务(正确地)针对某个可再现的错误抛出FaultException。单元测试获取WCF客户机的一个实例,并调用相应的服务方法,该方法引发FaultException 所有这些都如您所期望的那样工作,但是我很难对其进行单元测试,因为当服务实现中没有捕获到错误时,故障会导致IDE中断。因为我使用的是错误,而不是异常,所以我希望IDE序列化异常并将其发送到客户端,在客户端它将引发异常 我确实看到有一个配置选项可以

对WCF服务的预期故障进行单元测试的最佳方法是什么

我试图对一个WCF服务进行单元测试,该服务(正确地)针对某个可再现的错误抛出FaultException。单元测试获取WCF客户机的一个实例,并调用相应的服务方法,该方法引发FaultException

所有这些都如您所期望的那样工作,但是我很难对其进行单元测试,因为当服务实现中没有捕获到错误时,故障会导致IDE中断。因为我使用的是错误,而不是异常,所以我希望IDE序列化异常并将其发送到客户端,在客户端它将引发异常

我确实看到有一个配置选项可以禁用特定用户未处理异常的中断,但我希望有人能指出一个更好的方法来实现相同的结果,因为这在团队环境中不容易实现

下面是一些示例代码,说明了实现当前的样子

单元测试项目有一个对我的WCF服务的服务引用,我已将接口定义为:

[OperationContract(Name = "DoSomething")]
[FaultContract(typeof(EpicFail))]
ResponseObject DoSomething(RequestObject requestObject);
故障的定义如下:

[DataContract]
public class EpicFail
{

    public EpicFail(string action)
    {
        this.Reason = "Epic Fail";
        this.Action = action;
    }

    [DataMember]
    public string Reason
    {
        get;
        set;
    }

    [DataMember]
    public string Action
    {
        get;
        set;
    }

}
调用服务的代码大致如下所示:

[TestMethod()]
[ExpectedException(typeof(FaultException<EpicFail>))]
public void FaultTest_Fails_Epicly()
{
    bool testPassed = false;

    try
    {
        ResponseObject resp = GetServiceClient().DoSomething(req);
    }
    catch (FaultException<EpicFail>)
    {
        testPassed = true;
    }

    Assert.IsTrue(testPassed);
}
[TestMethod()]
[ExpectedException(typeof(FaultException))]
公共无效故障测试失败
{
bool testPassed=false;
尝试
{
ResponseObject resp=GetServiceClient().DoSomething(请求);
}
捕获(错误异常)
{
testPassed=true;
}
Assert.IsTrue(testPassed);
}
  • 我对代码进行了编辑,以显示我正在使用ExpectedException属性,并且它似乎对防止IDE/调试器在服务中引发异常时中断没有多大影响
您可以始终使用
ExpectedExceptionAttribute
(在NUnit中)来确保这是引发的异常。MSTest也有类似的概念

[ExpectedException(typeof(MyException))]
void my_test()
{
     // test
}
如果您有一些模拟验证要做,我会在catch中使用try/catch块和verify,然后抛出异常

更新

当您使用
ExpectedException
属性时,您不应该捕获异常,而是需要让运行测试的NUnit来捕获它

如果需要验证异常中的特殊信息,则捕获异常,验证信息,然后重试:

[ExpectedException(typeof(MyException))]
void my_test()
{
     try
     {
         // call the service
     }
     catch(MyException ex)
     {
          Assert.IsTrue(ex.Message.Contains("error code 200"));
          throw ex;
     }

}
马特夫

为什么此测试必须远程访问服务?从我看到的代码:

ResponseObject resp = GetServiceClient().DoSomething(req);
以某种方式获得服务客户端,而不是服务实例本身。我建议直接为单元测试测试服务混凝土类

但是,如果您需要此场景,您是否尝试过不捕获异常并运行测试?它会给出同样的结果吗

顺便说一句,如果您需要捕捉并重新捕获,请使用以下模式:

try {
   //Do something
}
catch(SomeException e) {
   //Do something with e
   throw
}

我实际上在单元测试中使用了ExpectedException属性。也许我用错了。我将在示例代码中附加我正在做的事情。好吧,谢谢你告诉我属性的正确用法-不幸的是,仍然没有解决我的问题。虽然现在当我在应用程序因异常而中断后恢复应用程序时,测试通过了!据我所知,你的问题是我提出建议的测试。对于应用程序问题,您没有共享任何内容,您认为我应该如何帮助您?我的问题是,当服务器端发生异常时,测试导致IDE中断,而不是我不知道如何断言测试已通过。我在这里说:“所有这些都如您所期望的那样工作,但是我很难对其进行单元测试,因为当服务实现中没有捕获到错误时,故障会导致IDE中断。" .... 请不要误会我的意思,我感谢您的帮助,您已经向我显示了我所犯的错误,但我的问题仍然存在。您是在与单元测试相同的进程中托管WCF服务,还是在单独的进程中托管WCF服务?单独的进程中,WCF服务通过IIS托管。我正在调试模式下本地运行单元测试。两个项目都是同一解决方案的一部分。我认为,如果在构建模式下运行服务,在调试模式下运行单元测试,可能会解决问题,但这似乎不是比IDE配置选项更好的解决方案。。这仍然是我必须为每个人的机器做的事情。您是否已将IDE配置为在所有异常情况下中断?远程访问服务背后的想法是测试以WCF客户端为中心的一些可伸缩性功能,因此我想测试远程连接的实现方式。我不确定这是否是最好的方法,真的,但我喜欢代码覆盖率。。。如果我没有捕获异常,测试将失败,这对于某些测试来说是准确的,但是在其他测试中,我真的希望测试是否抛出了错误。