.Net單元測試之NMock
示例
現在我們來做一個簡單的“Hello”例子,測試 Hello 類的 Greet() 方法,Hello 類依賴於一個 Person 物件,並將根據 Person 的名字向對應的賬號傳送祝賀(Greet)。這個例子很簡單,其實用不到模擬物件,不過用來理解 NMock 是很合適的。
{
string Name { get; }
}
然後定義具有 Greet 方法的 Hello 類,可以根據 IPerson 的名字傳送祝賀資訊。
publicclass Hello
{
IPerson person;
public Hello(IPerson person)
this.person = person;
}
public String Greet()
{
return"Hello "+ person.Name;
}
}
我們可以看到,Hello 類對 IPerson 介面有依賴。
在我們繼續對 Hello 類的開發之前,讓我們來學習一些關於 NMock 的基礎知識。使用 NMock 很容易根據一個給定的介面或類來建立一個模擬物件;
1)首先你要例項化一個 Mock 物件,構建時要將你要模擬的介面或類的型別傳遞給 Mock 物件作為構建引數;
2)然後,你需要記錄 Mock 物件的行為並最終通過 Mock 物件的屬性來獲得一個模擬型別的示例。下面是一個最簡單的窗體的模擬物件,該模擬物件基於 IPerson 介面建立,沒有記錄任何行為。
IMock mockPerson =new DynamicMock(typeof(IPerson));
//獲取指定型別的一個模擬例項
IPerson person = (IPerson) mockPerson.MockInstance;
然而如果我們不記錄模擬物件應該做些什麼或者在它使用之前需要做一些什麼處理,那麼實際上這個模擬物件是毫無用處的;在下面的例子中,我們將記錄並設定 IPerson 的 Name 屬性的值。
//通知 NMock 你在模擬哪個介面或類
IMock mockPerson =new DynamicMock(
mockPerson.ExpectAndReturn("Name", "John");
//獲取指定型別的一個模擬例項
IPerson person = (IPerson) mockPerson.MockInstance; NMock 有一個很長的很有用的 Expect 方法列表,使用這些列表我們可以設定模擬物件的行為,比如方法 A 被呼叫則返回 B,或者僅當用引數 C 呼叫方法 A 時才返回 B,或者當 A 方法被呼叫時則丟擲異常 E,甚至我們可以告訴模擬物件它根本就不要指望能夠呼叫方法 A。以上的簡單例子表明我們希望 Name 屬性只應該被呼叫一次,並且存取該屬性時將返回字串“John”;注意我們希望 Name 屬性只應該被呼叫一次,我們可以通過呼叫模擬物件的 Verify() 方法來驗證這一點。
//在模擬物件上的預期檢驗
person.Verify();
這是一個簡略的預期設定的方法列表:
Expect(string methodName, object[] args)
ExpectAndReturn(string methodName, object returnVal, object[] args)
ExpectAndThrow(string methodName, Exception exceptionVal, object[] args)
ExpectNoCall(string methodName)
現在設定好所有的基本條件,我們就可以簡單的在對 Hello 類的測試中應用 NMock 了。
這就是我們的測試類:
[TestFixture]
publicclass HelloTest : Assertion
{
[Test]
publicvoid TestExpect()
{
//模擬依賴
IMock person =new DynamicMock(typeof(IPerson));
//設定值
person.ExpectAndReturn("Name", "John");
Hello hello =new Hello((IPerson) person.MockInstance);
AssertEquals("Hello John", hello.Greet());
//檢驗 Name 屬性是否只被呼叫了一次
person.Verify();
}
}