簡體   English   中英

如何測試委托方法

[英]How to test a delegated method

我在類中有一個簡單的方法,負責在appconfig.xml中指定路徑的情況下注冊FileSystemWatcher:

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的單元測試?

非常感謝

在事件上注冊回調僅是填充變量。 或多或少將回調添加到回調列表中。 我通常不會驗證諸如列表填充之類的偶然事物,除非數據填充是類的整個要點(例如,如果類表示自定義數據結構)。

您可以改為在修改指定文件時驗證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
}

如果您有權訪問FileSystemWatcher則可以對其進行設置,以便模擬Created事件的觸發。 但是我懷疑並非如此,這意味着您到了真正的“單元測試”並非易事的地步。

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

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

您可以將方法分為兩種:第一種方法僅實例化,配置並返回FileSystemWatcher的實例。 然后,您可以輕松地對返回的結果對象進行測試。 第二種方法可以將其作為參數,並僅在其上啟用上升事件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM