技术宅,fat-man

增加语言的了解程度可以避免写出愚蠢的代码

导航

mock对象3:前进!用库和引用屏蔽掉业务对象和mock对象

引言

上次给我领导演示过mock对象,领导觉得很好,不过他觉得这个方案不完美,因为我们通过一个基类对象屏蔽掉了业务对象和mock对象,虽然从接口上看,看不出这两者的区别,但是对于现有程序,为了造出mock对象进行测试,还要先重构程序才能做到这一点,领导觉得不爽,他想要一种完全透明的解决方案,不修改现有的任何一行代码,就能在业务对象和mock对象之间进行切换,我想了一下,觉得似乎可以通过导入不同库来解决,也就是说我写一个动态链接库项目,定义和业务对象具有相同名字,方法,属性的类,由于上次演示的业务对象其实是系统的库(System.Messaging)系统库在.NET的技术框架下是通过引用导入到项目里的(Visual Studio .NET 项目/应用 右键添加应用 在.NET选项卡下选择System.Messaging)因此我们在自己的解决方案里添加一个Messaging动态链接库项目,它完全模拟系统库的行为,然后我们在使用系统库的项目里替换系统的动态链接库从而达到切换业务对象和mock对象的目的


使用业务对象的程序它的驱动模块(main函数)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Queue queue = new Queue();
            while (true)
            {
                string s = (string)queue.readMessage(typeof(string));
                Console.WriteLine(s);
            }
        }
    }
}

使用业务对象的模块

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Messaging;

namespace ConsoleApplication1
{
    class Queue
    {
        MessageQueue queue = null;

        public Queue()
        {
            string queueName = ".\\Private$\\TEST";
            if (MessageQueue.Exists(queueName))
            {
                queue = new MessageQueue(queueName);
            }
            else
            {
                queue = MessageQueue.Create(queueName, false);
                queue.SetPermissions("Everyone", MessageQueueAccessRights.FullControl);
            }
        }

        public object readMessage(Type elementType)
        {
            //因为真正的处理代码需要elementType可以读出
            System.Messaging.Message message = queue.Receive();
            message.Formatter = new XmlMessageFormatter(new Type[] { elementType });
            return (object)message.Body;
        }
    }
}

 


动态链接库代码:模拟业务对象的mock对象

/*
项目名称:Messaging
项目类型:动态链接库
功      能:模拟系统库System.Messaging的行为,别的项目引用该动态链接库就可以当作系统的库使用,主要配合测试
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace System.Messaging
{
    public enum MessageQueueAccessRights
    {
        FullControl = 983103
    }

    public class Message
    {
        public object Body;
        public object Formatter;
    }

    public class XmlMessageFormatter
    {
        public XmlMessageFormatter(Type[] targetTypeNames)
        { 
        
        }
    }

    public class MessageQueue
    {
        private int elementIndex = 0;
        private String[] elements = { "hello","world"};

        public static MessageQueue Create(string queueName, bool transactional)
        {
            return new MessageQueue();
        }

        public static bool Exists(string queueName)
        {
            return true;
        }

        public MessageQueue(string queueName = "")
        {
            
        }

        public void SetPermissions(string user, MessageQueueAccessRights rights)
        {
            //do nothing
        }

        public Message Receive()
        {
            Message message = new Message();
            if (elementIndex < elements.Length)
                message.Body = elements[elementIndex++];
            else
                System.Threading.Thread.Sleep(1000 * 60 * 60);
            return message;
        }
    }
}

END.

posted on 2012-11-19 14:02  codestyle  阅读(464)  评论(0编辑  收藏  举报