天天看點

Moq測試基礎說談(二)——Mock方法,方法參數

準備工作:

public interface ICustomer

{ }

(一)方法

(1)普通的方法

在接口中添加3個方法:

void AddCall();

string GetCall();

string GetCall(string strUser);

Mock測試:

var customer = new Mock<ICustomer>();

customer.Setup(p=>p.AddCall());

customer.Setup(p => p.GetCall()).Returns("phone:89898789");

customer.Setup(p => p.GetCall("Tom")).Returns("Hello");

customer.Object.AddCall();

Assert.AreEqual("phone:89898789", customer.Object.GetCall());

Assert.AreEqual("Hello", customer.Object.GetCall("Tom"));

先是建立Icustomer接口的mock對象:customer,這個對象執行Icustomer接口的業務。

然後對接口中的三個方法進行依賴添加:

這裡隻說第三個方法:

customer對象的GetCall方法,傳遞參數Tom,得到傳回值:Hello,相當于:

string GetCall(“Tom”){return “Hello”;}

測試,當調用無參數的GetCall()時,已經得知它會傳回:phone:89898789

當調用有參數的GetCall(string)時,如果參數是”Tom”,那麼傳回:Hello

(2)帶有引用或輸出參數的方法

string GetAddress(string strUser, out string Address);

string GetFamilyCall(ref string strUser);

var outString="oo";

customer.Setup(p => p.GetAddress("", out outString)).Returns("shijiazhuang");

customer.Setup(p => p.GetFamilyCall(ref outString)).Returns("xx");

(3)有傳回值的普通方法

還用string GetCall(string strUser);

這個進行測試,這裡可以操作參數:

customer.Setup(p => p.GetCall(It.IsAny<string>()))

.Returns((string s) => "Hello "+s);

Assert.AreEqual("Hello Tom",customer.Object.GetCall("Tom"));

GetCall方法傳回值是:Hello+調用參數

(4)調用方法時抛出異常

方法:void ShowException(string str);

測試:

customer.Setup(p => p.ShowException(string.Empty))

.Throws(new Exception("參數不能為空!"));

customer.Object.ShowException("");

如果傳入的參數是空值(string.Empty),那麼調用這個方法時(Mock調用)就會觸發異常。

(5)調用時指派

方法:void AddCall();

int iCount = 0;

customer.Setup(p => p.AddCall()).Callback(()=>iCount++);

Assert.AreEqual(0, iCount);

Assert.AreEqual(1, iCount);

Assert.AreEqual(2, iCount);

Assert.AreEqual(3, iCount);

(二)比對參數

customer.Setup(p => p.SelfMatch(It.IsAny<int>()))

.Returns((int k) => "任何數:" + k);

Console.WriteLine(customer.Object.SelfMatch(100));

customer.Setup(p => p.SelfMatch(It.Is<int>(i => i % 2 == 0)))

.Returns("偶數");

customer.Setup(p => p.SelfMatch(It.IsInRange<int>(0, 10, Range.Inclusive)))

.Returns("10以内的數");

Console.WriteLine(customer.Object.SelfMatch(8));

customer.Setup(p => p.ShowException(It.IsRegex(@"^\d+$")))

.Throws(new Exception("不能是數字"));

customer.Object.ShowException("r4");

It用于添加參數限制,它有以下幾個方法:

Is<T>:比對确定的給定類型

IsAny<T>:比對給定的任何值

IsInRange<T>:比對給定類型的範圍

IsRegex<T>:正則比對

通過示例來示範一下:

(1)Is<T>

customer.Setup(x => x.SelfMatch(It.Is<int>(i => i % 2 == 0))).Returns("1");

方法SelfMatch接受int型參數,當參數為偶數時,才傳回字元串1。

i=>i%2==0這個表達式的意思在以前的随筆中已經解釋過,詳細可見:

http://www.cnblogs.com/jams742003/archive/2009/12/23/1630737.html

(2)IsAny<T>

customer.Setup(p => p.SelfMatch(It.IsAny<int>())).Returns((int k) => "任何數:" + k);

方法SelfMatch接受int型,且任何int型參數都可以,然後傳回:"任何數:" + k。

這裡說明一下Returns方法:

Returns(Func<TResult>)

Returns<T>(Func<T,TResult>)

Returns<T1,T2>(Func<T1,T2,TResult>)

Returns<T1,T2,T3>(Func<T1,T2,T3,TResult>)

Returns<T1,T2,T3,T4>(Func<T1,T2,T3,T4,TResult>)

Returns(TResult)

在這個例子中,用到的就是第一種重載,關于Func委托,可以見我的:

http://www.cnblogs.com/jams742003/archive/2009/10/31/1593393.html

因為Func最多接受4個傳入參數(有5個重載),是以這裡的Returns帶有Func委托參數的重載也有5個。

(3)IsInRange<T>

方法SelfMatch接受int型,且當範圍在[0,10]時,才傳回10以内的數

其中,這個方法,帶有一個包含與排除開關。

(4)IsRegex<T>

部落格園大道至簡

http://www.cnblogs.com/jams742003/

轉載請注明:部落格園

繼續閱讀