日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

TDD Tip:方法内部New出来的对象如何Mock

發布時間:2025/4/5 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TDD Tip:方法内部New出来的对象如何Mock 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

解決的問題:方法內部new的對象在測試時希望能夠用mock對象去代替。

問題:以下方法可以解決,但是很是丑陋,各位大俠是否有更好的方法?

描述:如果說把內部的方法放到類的一個公開成員變量,或者放到方法的參數里,我的意見是公開了不應該公開的東西。

使用第三方的類庫: Mock工具 Rhino.Mocks, IOC: Castle.Windsor

1. 現在我又這么一段代碼,我想測試Math內部這兩個方法

????public??class?Math

??? {

????????public?long?MathAdd(int?a,?int?b)

??????? {

????????????Calc?c =?new?Calc();???????????

????????????return?c.Add(a, b);

??????? }

?

????????public?long?MathAdd2Price(int?a)

??????? {

????????????Calc?c =?new?Calc();

????????????return?c.AddCount(a) + c.count;

??????? }

??? }

?

????public?class?Calc

??? {

????????public?int?count = 0;

????????public?long?Add(int?a,?int?b)

??????? {

????????????return?a + b;

??????? }

?

????????public?long?AddCount(int?num)

??????? {

????????????return?count + num;

??????? }

??? }

?

2. 我們看到,由于是在內部new的對象,我們就對Calc類產生了很大的依賴,于是我想到注入一個對像,下面是我的設計

?

?? public?class?ContainerFactory

??? {

????????public static?IWindsorContainer?container;

????????public?bool?IsDebug =?false;

????????private?static?readonly?ContainerFactory?instance =?new?ContainerFactory();

?

????????public?static?ContainerFactory?Instance

??????? {

????????????get

??????????? {

????????????????return?instance;

??????????? }

??????? }

?

????????private?ContainerFactory()

??????? {

??????????? AddAllCompent();

??????? }

?

????????private?void?AddAllCompent()

??????? {

????????????if?(container ==?null)

??????????? {

??????????????? container =?new?WindsorContainer();

????????????????//此處職位演示,未使用接口

??????????????? container.AddComponentWithLifestyle<Calc>("Calc",?LifestyleType.Transient);??????????? }

??????? }

}

這樣我們的Math類可改成這樣

??public??class?Math

??? {

????????public?long?MathAdd(int?a,?int?b)

??????? {

???????????// Calc c = new Calc();

????????????Calc?c =(Calc)?ContainerFactory.container["Calc"];

????????????return?c.Add(a, b);

??????? }

?

????????public?long?MathAdd2Price(int?a)

??????? {

????????????Calc?c = (Calc)ContainerFactory.container["Calc"];

????????????return?c.AddCount(a) + c.count;

??????? }

?

??? }

?

3.? 但是,我們如何在測試中用我們Mock的對象代替真實的對象呢?下面是我想的一個自己也認為不好的方法,但能湊活著用

?public?class?ContainerFactory

??? {

????????private?IWindsorContainer?container;

????????public?bool?IsDebug =?false;

????????private?static?readonly?ContainerFactory?instance =?new?ContainerFactory();

?

????????public?static?ContainerFactory?Instance

??????? {

????????????get

??????????? {

????????????????return?instance;

??????????? }

??????? }

?

????????private?ContainerFactory()

??????? {

??????????? AddAllCompent();

??????? }

?

????????private?void?AddAllCompent()

??????? {

????????????if?(container ==?null)

??????????? {

??????????????? container =?new?WindsorContainer();

????????????????//此處職位演示,未使用接口

??????????????? container.AddComponentWithLifestyle<Calc>("Calc",?LifestyleType.Transient);??????????? }

??????? }

?

??????? #region?Calc

????????private?Calc?DebugCalc;

????????public?Calc??? Calc

??????? {

????????????get

??????????? {

????????????????if?(IsDebug && DebugCalc !=?null)

??????????????? {

????????????????????return?DebugCalc;

??????????????? }

????????????????else

??????????????? {

????????????????????return?(Calc)container["Calc"];

??????????????? }

??????????? }

????????????set

??????????? {

????????????????// just for test, for mock object

????????????????if?(IsDebug)

??????????????? {

??????????????????? DebugCalc =?value;

??????????????? }

????????????????else

??????????????? {

????????????????????throw?new?Exception("just for test");

??????????????? }

??????????? }

??????? }

??????? #endregion?

??? }

修改我們的類

??public??class?Math

??? {

????????public?long?MathAdd(int?a,?int?b)

??????? {

???????????// Calc c = new Calc();

????????????Calc?c =?ContainerFactory.Instance.Calc;

????????????return?c.Add(a, b);

??????? }

?

????????public?long?MathAdd2Price(int?a)

??????? {

????????????Calc?c =?ContainerFactory.Instance.Calc;

????????????return?c.AddCount(a) + c.count;

??????? }

?

??? }

?

這樣我們來看我們通過了測試的代碼

[TestClass()]

????public?class?MathTest

??? {

??????? [TestMethod()]

????????public?void?MathAddTest()

??????? {

????????????Math?m =?new?Math();

?

????????????// 想讓真實代碼內部,使用的是Mock的對象

????????????// Arrange

????????????MockRepository?mocks =?new?MockRepository();

????????????Calc?mockCalc = mocks.Stub<Calc>();

??????????? mockCalc.count = 5;

????????????ContainerFactory.Instance.IsDebug =?true; //這句很重要

????????????ContainerFactory.Instance.Calc = mockCalc;

?

??????????? mocks.ReplayAll();

????????????// Act

????????????Assert.AreEqual(m.MathAdd(5, 5), 10);

????????????Assert.AreEqual(mockCalc.AddCount(6), 11);

??????????? mocks.VerifyAll();

?

????????????Calc?mockCalc2 = mocks.Stub<Calc>();

??????????? mocks.ReplayAll();

?

????????????// 這里有問題,我們希望他是7,但實際是12,因為需要測試中的和實際代碼用同一個對象,

????????????// 他保留上次的狀態count的值5

????????????Assert.AreEqual(mockCalc.AddCount(7), 12);

??????????? mocks.VerifyAll();???????????

??????? }

?

??????? [TestMethod]

????public?void?MathAddTestActual()

??? {

????????????//這里測試實際使用代碼,沒用Mock

????????Math?m =?new?Math();

????????Assert.AreEqual(m.MathAdd(5,6), 11);

????????Assert.AreEqual(m.MathAdd2Price(9), 9);

????????Calc?c =?ContainerFactory.Instance.Calc;

????????Assert.AreEqual(c.AddCount(5), 5);

??????? c.count = 20;

????????Assert.AreEqual(c.AddCount(5), 25);

????????Calc?d =?ContainerFactory.Instance.Calc;

????????Assert.AreEqual(d.AddCount(30), 30);

????????Assert.AreEqual(c.count, 20);

????????Assert.AreEqual(d.count, 0);

??? }

??? }

?

?

總結:這樣可以不使用用public的類成員變量,不用通過方法參數注入注入對象

?

問題:? ContainerFactory代碼較多,測試時需要設標志。

?

其它的問題: 等待高人指出,謝謝!

本文轉自敏捷的水博客園博客,原文鏈接http://www.cnblogs.com/cnblogsfans/archive/2008/12/16/1355640.html如需轉載請自行聯系原作者


王德水

總結

以上是生活随笔為你收集整理的TDD Tip:方法内部New出来的对象如何Mock的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。