wcf - 单元测试 Web 服务的推荐模式

标签 wcf web-services unit-testing rest soa

我们即将开始构建面向服务的框架 (SOA),它肯定会涉及大量细粒度的 Web 服务(WCF 中的 REST)。我们在对客户端和服务器端代码库进行单元测试方面非常严格,但是我们在单元测试 Web 服务方面没有太多经验。我们真的在寻找关于应该在哪里编写测试的指导以及在对我们的服务进行单元测试时使用什么方法的建议。

我们是否应该编写发出 http 请求的测试并断言响应是它们应该的样子?我们是否应该只专注于测试服务方法本身的内部逻辑,而不必担心测试实际请求?还是我们应该两者都做?对于我们应该测试的内容,还有其他建议吗?

我们真的在寻找一些解释和指导,并且非常感谢我们能得到的任何建议。

最佳答案

我发现测试 Web 服务,特别是 WCF 客户端和服务器,在以下场景中在常规单元测试之上非常有用:

  • 验收测试,您希望黑盒测试您的整个服务并在四肢插入一些东西。
  • 测试特定的 WCF 连接、扩展、行为等。
  • 测试您的界面和数据成员是否设置正确。

  • 大多数时候,我尝试使用带有基本 http 的非常基本的设置并将所有内容连接到代码中。除非我是集成或验收测试,否则我不会针对服务器测试客户端,而是模拟其中一个,以便我可以单独测试另一个。以下是我如何测试 WCF 客户端和服务的示例:

    public static ServiceHost CreateServiceHost<TServiceToHost>(TServiceToHost serviceToHost, Uri baseAddress, string endpointAddress)
    {
        var serviceHost = new ServiceHost(serviceToHost, new[] { baseAddress });
    
        serviceHost.Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true;
        serviceHost.Description.Behaviors.Find<ServiceBehaviorAttribute>().InstanceContextMode = InstanceContextMode.Single;
    
        serviceHost.AddServiceEndpoint(typeof(TServiceToHost), new BasicHttpBinding(), endpointAddress);
    
        return serviceHost;
    }
    
    //Testing Service
    
    [TestFixture]
    class TestService
    {
        private ServiceHost myServiceUnderTestHost;
        private ChannelFactory<IMyServiceUnderTest> myServiceUnderTestProxyFactory;
        [SetUp]
        public void SetUp()
        {
            IMyServiceUnderTest myServiceUnderTest = new MyServiceUnderTest();
            myServiceUnderTestHost = CreateServiceHost<IMyServiceUnderTest>(myServiceUnderTest, new Uri("http://localhost:12345"), "ServiceEndPoint");
            myServiceUnderTestHost.Open();
    
            myServiceUnderTestProxyFactory = new ChannelFactory<IMyServiceUnderTest>(new BasicHttpBinding(), new EndpointAddress("http://localhost:12345/ServiceEndPoint")); 
        }
    
        [TearDown]
        public void TearDown()
        {
            myServiceUnderTestProxyFactory.Close();
            myServiceUnderTestHost.Close();
        }
    
        [Test]
        public void SomeTest() 
        {
            IMyServiceUnderTest serviceProxy = myServiceUnderTestProxyFactory.CreateChannel();
    
            serviceProxy.SomeMethodCall();
        }
    }
    
    //Testing Client
    
    [TestFixture]
    class TestService
    {
        private ServiceHost myMockedServiceUnderTestHost;
        private IMyServiceUnderTest myMockedServiceUnderTest;
    
        [SetUp]
        public void SetUp()
        {
            myMockedServiceUnderTest = Substitute.For<IMyServiceUnderTest>(); //Using nsubstitute
            myServiceUnderTestHost = CreateServiceHost<IMyServiceUnderTest>(myMockedServiceUnderTest, new Uri("http://localhost:12345"), "ServiceEndPoint");
            myServiceUnderTestHost.Open();
        }
    
        [TearDown]
        public void TearDown()
        {
            myServiceUnderTestHost.Close();
        }
    
        [Test]
        public void SomeTest() 
        {
            //Create client and invoke methods that will call service
            //Will need some way of configuring the binding
            var client = new myClientUnderTest();
    
            client.DoWork();
    
            //Assert that method was called on the server
            myMockedServiceUnderTest.Recieved().SomeMethodCall();
        }
    }
    

    注意

    我忘了提到,如果你想使用任何使用城堡动态代理的东西来模拟 WCF 服务,那么你需要阻止 ServiceContractAttribute从被复制到模拟。我有一个 blog post在这一点上,但基本上您将属性注册为一个以防止在创建模拟之前复制。
    Castle.DynamicProxy.Generators.AttributesToAvoidReplicating
      .Add<ServiceContractAttribute>();
    

    关于wcf - 单元测试 Web 服务的推荐模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9587393/

    相关文章:

    python - 我可以从不同的目录运行 django 测试 (manage.py) 吗?

    java - Grails Spock - 从服务抛出异常 UndeclaredThrowableException

    c# - 返回 XML 而非 JSON 的 RESTful Web 服务

    javascript - Asmx Web服务引用问题

    java - 记录 SOAP 消息

    c# - 如何使用 HTTPRequestMessage 添加 SOAP 身份验证 header ?

    Django 1.4 说 "No database fixture specified. Please provide the path of at least one fixture in the command line."

    c# - 基于证书的认证基础

    c# - 如何在客户端打开 WCF 跟踪?

    c# - 使用 HttpRequestMessage 或 Stream 上传 REST 文件?