MOQ TIP1:简介加基础
MOQ來自于http://code.google.com/p/moq/。下載后其實(shí)是直接作為DLL被引用的。
Mock是模擬對(duì)象的一種技術(shù)。
它可以用于以下情況:
----- 真實(shí)對(duì)象具有不可確定的行為(產(chǎn)生不可預(yù)測(cè)的結(jié)果,如股票的行情)
----- 真實(shí)對(duì)象很難被創(chuàng)建(比如具體的web容器)
----- 真實(shí)對(duì)象的某些行為很難觸發(fā)(比如網(wǎng)絡(luò)錯(cuò)誤)
----- 真實(shí)情況令程序的運(yùn)行速度很慢
----- 真實(shí)對(duì)象有用戶界面
----- 測(cè)試需要詢問真實(shí)對(duì)象它是如何被調(diào)用的(比如測(cè)試可能需要驗(yàn)證某個(gè)回調(diào)函數(shù)是否被調(diào)用了)
----- 真實(shí)對(duì)象實(shí)際上并不存在(當(dāng)需要和其他開發(fā)小組,或者新的硬件系統(tǒng)打交道的時(shí)候,這是一個(gè)普遍的問題)
1:測(cè)試返回值
需要被測(cè)試的代碼:
| public?interface?ICounter { ????int?CountArgs(int?a, int?b); } public?class?SampleClass { ????private?ICounter _counter; ????public?SampleClass(ICounter counter) ????{ ????????_counter = counter; ????} ????public?int?GetResoult() ????{ ????????return?_counter.CountArgs(1, 2) + 3; ????} } |
測(cè)試代碼:
| Mock<ICounter> mock = new?Mock<ICounter>(); mock.Setup(counter => counter.CountArgs(1, 2)).Returns(3); SampleClass sample = new?SampleClass(mock.Object); int?re = sample.GetResoult(); mock.Verify(); Assert.AreEqual(re, 6); |
2:測(cè)試拋出異常
假設(shè)待測(cè)試代碼為:
| public?interface?ICounter { ????int?CountArgs(int?a, int?b); } public?class?SampleClass { ????private?ICounter _counter; ????public?SampleClass(ICounter counter) ????{ ????????_counter = counter; ????} ????public?int?GetResoult() ????{ ????????return?_counter.CountArgs(100, 123) + 3; ????} } |
測(cè)試代碼則為:
| Mock<ICounter> mock = new?Mock<ICounter>(); mock.Setup(arg => arg.CountArgs(100, 123)).Throws(new?ArgumentException("參數(shù)過大")); SampleClass sample = new?SampleClass(mock.Object); try { ????int?re = sample.GetResoult(); ????mock.Verify(); } catch?(ArgumentException) { ????return; } Assert.Inconclusive("error"); |
3:一些限制
MOQ可以直接模擬接口,但是在模擬類的時(shí)候,有如下限制:
類不能是密封的;
方法要加上虛修飾符;
不能模擬靜態(tài)方法(可以通過適配器模式來模擬靜態(tài)方法);
其實(shí)這些限制中,一般來說我們是不需要模擬類的,但是抽象類還是需要模擬的比較多,比如:
| public?abstract?class?CounterBase { ????public?abstract?int?CountArgs(int?a, int?b); ????public?int?ArgProp { get; set; } ????public?virtual?string?GetSomethingVitual() ????{ ????????return?ArgProp.ToString(); ????} ????public?string?GetSomethingReal() ????{ ????????return?"abc"; ????} } public?class?SampleClass { ????private?CounterBase _counter; ????public?SampleClass(CounterBase counter) ????{ ????????_counter = counter; ????} ????public?int?GetResult() ????{ ????????return?_counter.CountArgs(1, 2) + 3; ????} ????public?string?GetVitual() ????{ ????????return?_counter.GetSomethingVitual(); ????} ????public?string?GetReal() ????{ ????????return?_counter.GetSomethingReal(); ????} } |
在這里,作為調(diào)用者SampleClass來說,由于使用到了CounterBase,所以CounterBase 這個(gè)抽象類就是有必要被模擬的。SampleClass演示了調(diào)用抽象方法、虛方法、普通方法,運(yùn)行的結(jié)果是:
| ------ Test started: Assembly: TestProject1.dll ------ Test 'TestProject1.ProgramTest.TestReal'?failed: Test method TestProject1.ProgramTest.TestReal threw exception: System.NotSupportedException: Invalid setup on?a non-virtual?(overridable in?VB) member: arg => arg.GetSomethingReal() ????at Moq.Mock.ThrowIfCantOverride(Expression setup, MethodInfo method) ????at Moq.Mock.<>c__DisplayClass1c`2.<Setup>b__1b() ????at Moq.PexProtector.Invoke[T](Func`1 function) ????at Moq.Mock.Setup[T,TResult](Mock mock, Expression`1 expression, Func`1 condition) ????at Moq.Mock`1.Setup[TResult](Expression`1 expression) ????ProgramTest.cs(101,0): at TestProject1.ProgramTest.TestReal() 2 passed, 1 failed, 0 skipped, took 1.32 seconds (MSTest 10.0). |
我們可以看到,前面兩個(gè)方法都成功,只有那個(gè)非虛擬的普通方法失敗,信息如下:
Invalid setup on a non-virtual (overridable in VB) member: arg => arg.GetSomethingReal()
本文轉(zhuǎn)自最課程陸敏技博客園博客,原文鏈接:http://www.cnblogs.com/luminji/archive/2011/08/15/2136351.html,如需轉(zhuǎn)載請(qǐng)自行聯(lián)系原作者
總結(jié)
以上是生活随笔為你收集整理的MOQ TIP1:简介加基础的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 缺少物联网杀手级应用的运营商,到底该怎么
- 下一篇: (转)基于MVC4+EasyUI的Web