zoukankan      html  css  js  c++  java
  • 单元测试WCF服务之点滴

        有没有试过在单元测试中调用自己写的WCF服务?

        该不会还是添加一个服务引用再测试吧...

        这里就介绍一个非常简单的方式直接调用自己的WCF服务。

    1.启动服务

        首先,需要启动自己的WCF服务,如果服务没起来,在怎么调用也是白搭。

        当然这些代码都是大同小异的,所以干脆封装成一个扩展方法:

            public static void RunWcfService(this Type type, Action action)
            {
                var host = new ServiceHost(type);
                try
                {
                    host.Open();
                    action();
                }
                finally
                {
                    if (host.State == CommunicationState.Faulted)
                        host.Abort();
                    else
                        host.Close();
                }
            }

         这里直接在类型上添加了一个扩展方法,当这个类型是一个服务的实现,并且配置文件中有相关的配置(需要把config里面的必要信息复制到测试工程的app.config中)时,这个扩展方法可以正常执行。

        在action内的执行的代码时,这个服务一直处于打开状态。

    2.创建客户端

        只有服务端还不行,还需要一个客户端,需要生成客户端的代码吗?

        如果还需要生成Client的代理类不是又在自己给自己找麻烦了嘛,别忘了WCF客户端还可以用ChannelFactory来生成:

            public static void InvokeWcfClient<TChannel>(
                this Uri uri, Binding binding, Action<TChannel> action)
                where TChannel : class
            {
                TChannel client = ChannelFactory<TChannel>.CreateChannel(
                    binding, new EndpointAddress(uri));
                var co = (ICommunicationObject)client;
                try
                {
                    co.Open();
                    action(client);
                }
                finally
                {
                    if (co.State == CommunicationState.Faulted)
                        co.Abort();
                    else
                        co.Close();
                }
            }

        其中TChannel就是服务契约(也就是通常的那个接口),Binding是服务的Binding方式,如果服务端使用的是标准的Binding,那就直接new那个标准Binding就可以了(例如:NetTcpBinding),Uri是服务配置中侦听的的地址。

    3.例子

        现在有了这两个扩展方法,看看怎么写单元测试吧:

            [ServiceContract]
            public interface IHelloWorld
            {
                [OperationContract]
                string SayHello();
            }
    
            public class HelloWorld
                : IHelloWorld
            {
                public string SayHello()
                {
                    return "Hello world";
                }
            }
    
            [TestMethod]
            public void TestSayHello()
            {
                Uri uri = new Uri("net.tcp://localhost:8765/vwxyzh/helloworld/");
                typeof(HelloWorld).RunWcfService(() =>
                {
                    uri.InvokeWcfClient<IHelloWorld>(new NetTcpBinding(),
                        client =>
                        {
                            Assert.AreEqual("Hello world", client.SayHello());
                        });
                });
            }

        是不是很简单,当然,别忘了HelloWorld的配置,否则在创建服务的时候会因为找不到配置而导致异常。

  • 相关阅读:
    概率的定义
    二项式分布与伯努利分布
    复数的表示方法
    <诗经>的由来
    王国维
    应该记住的历史事件
    switch条件变量的取值类型
    & 和 && 区别和联系,| 和 || 区别和联系
    成功安装 Visio 2016 和 Office 2016 的64位版本~~
    删除MicrosoftOffice2016的扫尾工作
  • 原文地址:https://www.cnblogs.com/vwxyzh/p/1700526.html
Copyright © 2011-2022 走看看