前面出于演示目的,使用的都是一个个小的示例代码。这里模拟一下使用Moq真实场景。
假设要写个蜘蛛,我们有个接口叫IHttpClient负责连接到指定网站,PageEntity用于存储抓取页面信息。SpiderEngine则负责通过IHttpClient将目标页面上XPath指定的内容存到PageEntity中。
现在要测试SpiderEngine,单元测试嘛,既然我们选择测试SpiderEngine,就尽量不要依赖IHttpClient的具体实现。我们通过Moq模拟IHttpClient的实现进而测试SpiderEngine。
IHttpClient.cs
namespace FirstTest.SampleClasses { public interface IHttpClient { string Url { get; set; } string GetXpathContent(string xpathExp); } } |
PageEntity.cs
namespace FirstTest.SampleClasses { public class PageEntity { public PageEntity() { Sid = Guid.NewGuid(); } public static PageEntity CreatePageEntity() { return new PageEntity { Sid = Guid.NewGuid() }; } public Guid Sid { get; set; } public string Url { get; set; } public string XpathExp { get; set; } public string Content { get; set; } } } |
SpiderEngine.cs
namespace FirstTest.SampleClasses { public class SpiderEngine { #region Constructors public SpiderEngine(IHttpClient client) { this.httpClient = client; } #endregion #region Fields private IHttpClient httpClient; #endregion public void BuildPage(ref PageEntity page) { if (string.IsNullOrEmpty(page.Url) || string.IsNullOrEmpty(page.XpathExp)) throw new Exception("BuildPage must be configured"); httpClient.Url = page.Url; page.Content = httpClient.GetXpathContent(page.XpathExp); } } } |
UnitTest
/// <summary> /// 演练:在实际项目中使用Moq /// </summary> //[TestMethod] [Owner("wJiang")] public void MoqInFact() { string url = ""; //Mock IHttpClient Object var mo = new Mock<IHttpClient>(); //Set its behaviors mo.Setup( p => p.GetXpathContent(It.IsAny<string>())) .Returns("Hello Cnblogs!" + mo.Object.Url) .Callback( () => url = mo.Object.Url ); mo.SetupAllProperties(); //procedure test SpiderEngine engine = new SpiderEngine(mo.Object); PageEntity page = new PageEntity { XpathExp = "\\items", Url = "http://www.wjiangathpc.spaceslive.com" }; engine.BuildPage(ref page); //Asserts Assert.AreEqual(url, page.Url); Assert.AreEqual(page.Content, "Hello Cnblogs!"); } |