Mock object framework (1)

Source: The art of unit testing with examples in .NET, Roy Osherove
http://www.amazon.com/Art-Unit-Testing-Examples-Net/dp/1933988274/ref=sr_1_1?ie=UTF8&s=books&qid=1267086529&sr=1-1
Chapter 5 Isolation (mock object) framework

由前一個章節可以知道, 若是要自己撰寫stub或是mock, 會很花時間. 若是受測程式的interface很複雜, method很多, parameter很多, 都會使難度變高.

所以若是有個mock object framework來幫助我們處理這些事情, 將會大大解省開發的代價. 在這裡作者要和我們推薦的是Rhino Mock, 你可以在http://ayende.com中下載它們

這裡我們先來看若是沒有用Rhino Mock, 那測試程式會怎麼寫
// 受測程式
public class LogAnalyzer {
  private IWebService service;
 
  public LogAnalyzer(IWebService service) {
    this.service = service;
  }
 
  public void Analyze(string filename) {
    if (filename.Length < 8 ) {
      service.LogError("Filename too short:" + filename );
    }
  } 
}

// 自己實作mock object
public class ManualMockService: IWebService {
  public string LastError;
 
  public void LogError(string message) {
    LastError = message;
  }
}

[TestFixture]
public class LogAnalyzerTests {
  [Test]
  public void Analyze_TooShortFileName() {
  
    ManualMockService mockService = new ManualMockService();
   
    LogAnalyzer log = new LogAnalyzer( mockService);
 
    string tooShortFileName = "abc.ext";
    log.Analyze(tooShortFileName);
   
    Assert.AreEqual("Filename too short: abc.ext", mockService.LastError );
  } 
}

改成使用Rhino Mocks會變成這樣:
[Test]
public void Analyze_TooShortFileName() {
  // create dynamic mock object
  MockRepository mocks = new MockRepository();
  IWebService simulatedServoce = mocks.StrictMock<IWebService>();
 
  // 在這裡你要先紀錄哪個method要被叫
  // 會傳入哪些資料
  // 以供之後比對是否真實情況是這樣使用
  using(mocks.Record()) {
    simulatedServoce.LogError("Filename too short: abc.ext");
  }
 
  // invokes LogAnalyzer
  LogAnalyzer log = new LogAnalyzer( simulatedServoce);
  string tooShortFileName = "abc.ext";
  log.Analyze(tooShortFileName);
 
  // 比對受測程式是否以預期的方式呼叫
  mocks.Verify(simulatedServoce);
}

有沒有覺得用mock object library比較省力, 你不用真的實作interface, 並且比對結果也比較簡單. 

arrow
arrow
    全站熱搜

    kojenchieh 發表在 痞客邦 留言(0) 人氣()