2010-11-12 49 views
0

我有一個類,它是負責註冊一個FileSystemWatcher的給出appconfig.xml某一路徑的簡單方法:如何測試委派方法

public void ListenPath(string path){ 
    //path validation code 
    //... 

    FileSystemWatcher objFileWatcher = new FileSystemWatcher(); 
     objFileWatcher.Path = path; 
     objFileWatcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite 
     | NotifyFilters.FileName | NotifyFilters.DirectoryName; 
     objFileWatcher.Filter = "*.txt"; 
     objFileWatcher.Created += new FileSystemEventHandler(ProcessInput); 
     objFileWatcher.EnableRaisingEvents = true; 
} 

在我的單元測試我斷言:

1)是否有錯誤或空路徑應該引發PathNotFoundException

2)該ProcessInput方法是正確的註冊聽「路徑」創建文件時。

如何執行項目2的單元測試?

非常感謝

+0

嗯,事實上我想我可以編寫創建文件池時,該方法被解僱的測試。然後,在單元測試中在dir中創建一個文件,並查看添加的文件是否與池中的文件匹配... – Robert 2010-11-12 18:39:27

回答

1

在事件上註冊回調只是填充變量。它或多或少地向回調列表添加回調。我通常不會驗證偶然的東西,比如列表的種羣,除非數據是整個類的一部分(就像類表示自定義數據結構一樣)。

您可以改爲在修改指定文件時調用ProcessInput。有幾種方法可以解決這個問題:

  • ProcessInput的測試副作用,例如,它在您的程序中填充了一些其他結構或屬性
  • ProcessInput方法分離爲另一個類或接口。請參考此類型作爲參數ListPath或該類的構造函數。然後嘲笑這種類型

模仿對象例如:

public interface IInputProcessor 
{ 
    void ProcessInput(Object sender, FileSystemEventArgs e); 
} 

public class ClassUnderTest 
{ 
    public ClassUnderTest(IInputProcessor inputProcessor) 
    { 
     this.inputProcessor = inputProcessor; 
    } 

    public void ListenPath(string path){ 
     // Your existing code ... 
     objFileWatcher.Created += 
      new FileSystemEventHandler(inputProcessor.ProcessInput); 
     // ... 
    } 

    private IInputProcessor inputProcessor; 
} 

public class MockInputParser : IInputProcessor 
{ 
    public MockInputParser() 
    { 
     this.Calls = new List<ProcessInputCall>(); 
    } 

    public void ProcessInput(Object sender, FileSystemEventArgs args) 
    { 
     Calls.Add(new ProcessInputCall() { Sender = sender, Args = args }); 
    } 

    public List<ProcessInputCall> Calls { get; set; } 
} 

public class ProcessInputCall 
{ 
    public Object Sender; 
    public FileSystemEventArgs Args; 
} 

[Test] 
public void Test() 
{ 
    const string somePath = "SomePath.txt"; 
    var mockInputParser = new MockInputParser(); 
    var classUnderTest = new ClassUnderTest(mockInputParser); 
    classUnderTest.ListenPath(somePath); 
    // Todo: Write to file at "somePath" 
    Assert.AreEqual(1, mockInputParser.Calls.Count); 
    // Todo: Assert other args 
} 
0

如果FileSystemWatcher是您可以訪問,你可以設置它,這樣你可以嘲笑Created在觸發事件東西。但我懷疑它不是,這意味着你在這裏真正的「單元測試」不是很容易。

您可以嘗試使用TypeMock或Moles等隔離器來模擬Created事件的觸發。但最簡單的事情可能是實際編寫一個在給定路徑上創建文件的測試,並確保在發生這種情況時調用ProcessInput方法。

因爲您沒有在ProcessInput本身顯示定義或任何其他代碼,所以我不知道確保它被調用的最佳方法。

0

您可以將您的方法分成兩部分:第一個方法只是實例化,配置並返回FileSystemWatcher的實例。然後您可以輕鬆測試返回的結果對象。第二種方法可以將其作爲參數,並簡單地啓用上升事件。