引言
上次給我領導示範過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.