单元测试 WCF 错误

发布于 2024-09-29 23:59:34 字数 1426 浏览 5 评论 0原文

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

我正在尝试对 WCF 服务进行单元测试,该服务(正确地)针对某个可重现的错误抛出FaultExceptions。单元测试获取 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);
}
  • 我编辑了代码以表明我正在使用 ExpectedException 属性,并且它似乎对防止 IDE/调试器在服务中引发异常时中断没有太大作用。

What's the best way to unit test expected faults from WCF services?

I am attempting to unit test a WCF service which is (correctly) throwing FaultExceptions for a certain reproducible error. The unit tests get an instance of the WCF client and call the applicable service method, which throws a FaultException.

All of that works as you would expect, but I am having difficulty unit testing this, because the fault causes the IDE to break when the error isn't caught in the service implementation. Because I am using faults, and not exceptions, I was expecting the IDE to serialize the exception and send it to the client, where it would raise an exception.

I do see that there is a configuration option to disable breaking for specific user-unhandled exceptions, but I was hoping somebody could point out a better way to achieve the same results, as this isn't easily doable in a team environment.

Here's some sample code of what the implementation currently looks like...

The unit test project has a service reference to my WCF service, and I have defined the interface as such:

[OperationContract(Name = "DoSomething")]
[FaultContract(typeof(EpicFail))]
ResponseObject DoSomething(RequestObject requestObject);

The fault is defined as such:

[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;
    }

}

The code that calls the service looks vaguely like this:

[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);
}
  • I edited the code to show that I am using the ExpectedException attribute and it doesn't seem to be having much effect on keeping the IDE/Debugger from breaking when the exception is thrown in the service.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

安人多梦 2024-10-06 23:59:34

您始终可以使用 ExpectedExceptionAttribute (在 NUnit 中)来确保这是抛出的异常。 MSTest 也有类似的概念。

[ExpectedException(typeof(MyException))]
void my_test()
{
     // test
}

如果您需要进行一些模拟验证,我将使用 try/catch 块并在 catch 中进行验证,然后抛出异常。

UPDATE

当您使用 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;
     }

}

You can always use ExpectedExceptionAttribute (in NUnit) to make sure this is the exception thrown. MSTest has similar concept as well.

[ExpectedException(typeof(MyException))]
void my_test()
{
     // test
}

If you have some Mock verification to do, I would use try/catch block and verify in the catch and then throw the exception.

UPDATE

When you are using ExpectedException attribute, you are not supposed to catch the exception, instead you need to let the NUnit that runs your test to catch it.

If you need to verify special information in the exception then you catch the exception, verify the information and then rethrow:

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

}
相思碎 2024-10-06 23:59:34

mattv,

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

ResponseObject resp = GetServiceClient().DoSomething(req);

以某种方式获取服务客户端,而不是服务实例本身。我建议直接测试服务具体类以进行单元测试。

但是,如果您需要这种情况,您是否尝试过不捕获异常并运行测试?它给出相同的结果吗?

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

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

mattv,

Why does this test has to access the service remotely? From what I see your code:

ResponseObject resp = GetServiceClient().DoSomething(req);

Is somehow getting a service client, and not a service instance itself. I'd advise to test the service concrete class directly for unit tests.

However, if you need this scenario, have you tried NOT CATCHING the exception and running the test? Does it give the same result?

And by the way, if you need to catch and rethrow use the following pattern:

try {
   //Do something
}
catch(SomeException e) {
   //Do something with e
   throw
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文