2016-01-29 54 views
0

我編寫了一個用於檢查文件路徑的測試用例。在那個測試用例中,我使用Expected異常,然後我想知道如果該方法不會拋出文件未找到異常會發生什麼。處理預期的單元測試異常C#

例如,我在另一個系統中運行測試用例,如果系統中存在給定的文件路徑,測試將失敗。但它不應該是,測試用例應該總是通過。

如何處理這種情況,因爲單元測試不依賴於任何示例應該不依賴於機器?

測試的情況下......

string sourceFilePath = @"C:\RipWatcher\Bitmap.USF_C.usf"; 

string targetDirectory = @"C:\UploadedRipFile\"; 

[Test] 
[ExpectedException(typeof(FileNotFoundException))] 
public void InvalidSourceFilePathThrowsFileNotFoundException() 
{ 
    logWriter= new Mock<LogWriter>().Object; 

    ripfileUploader = new RipFileUploader(logWriter); 

    ripfileUploader.Upload(@"D:\RipWatcher\Bitmap.USF_C.usf",  
    targetDirectory);    
} 

方法..

public void Upload(string sourceFilePath, string targetFilePath) 
{ 
    if (!File.Exists(sourceFilePath)) 
    { 
     throw new FileNotFoundException(string.Format("Cannot find the file: {0}", sourceFilePath)); 
    } 

    if (!Directory.Exists(targetFilePath)) 
    { 
     throw new DirectoryNotFoundException(string.Format("Cannot find the Directory: {0}", targetFilePath)); 
    } 
    try 
    { 
     fileCopyEx.CopyEx(sourceFilePath,targetFilePath);    
    } 
    catch (Exception ex) 
    { 
     throw new Exception(string.Format("Failed to move file {0}", sourceFilePath), ex);   
    }   
} 
+3

「不應該依賴於機器」 - 是的,它不應該。但它*確實* - 因爲你是這樣寫的。它取決於本地文件系統上目錄的存在。 – BartoszKP

+0

這裏的測試是一個集成測試,而不是一個單元測試,因爲它測試文件系統以及使用它的代碼。如果您使代碼可測試並使用單元測試,問題就會消失 - 抽象文件和目錄類並使用可以模擬的接口。 –

回答

2

如果你想要這樣的方法是可測試的並且獨立於機器運行 - 你不應該直接使用FileDirectory類。

取而代之的是從您需要的所有類中提取具有方法的接口,編寫該接口的實現,該接口使用FileDirectory類的方法。

public interface IFileManager 
{ 
    bool IsFileExists(string fileName); 
    .... 
} 

public class FileManager : IFileManager 
{ 
    public bool IsFileExists(string fileName) 
    { 
     return File.Exists(fileName); 
    } 
} 

public void Upload(string sourceFilePath, string targetFilePath, IFileManager fileManager) 
{ 
    if (!fileManager.IsFileExists(sourceFilePath)) 
    { 
     .... 
    } 
} 

在工作環境中,您將使用此實現,並且在測試環境中,您必須創建實現此接口的模擬對象。所以你可以用你需要的任何方式設置這個模擬。

[Test] 
[ExpectedException(typeof(FileNotFoundException))] 
public void InvalidSourceFilePathThrowsFileNotFoundException() 
{ 
    fileManager = new Mock<IFileManager>();   
    fileManager.Setup(f => f.IsFileExists("someFileName")).Returns(false); 

    ripfileUploader = new RipFileUploader(logWriter); 

    ripfileUploader.Upload(@"D:\RipWatcher\Bitmap.USF_C.usf", 
          targetDirectory, 
          fileManager.Object);    
} 
+2

優秀的答案,但我會補充說,你應該避免使用ExpectedException屬性。它在NUnit 3中被刪除,因爲它被認爲是不好的做法。如果另一個調用與構造函數一樣引發相同的異常,那麼您的單元測試將錯誤地傳遞。相反,你應該只在Assert.Throws(...)中包裝你的上傳調用; –

0

如果你想確定的結果,你必須確保該文件沒有任何計算機上存在。

string sourceFilePath = @"C:\RipWatcher\Bitmap.USF_C.usf"; 

string targetDirectory = @"C:\UploadedRipFile\"; 

[Test] 
[ExpectedException(typeof(FileNotFoundException))] 
public void InvalidSourceFilePathThrowsFileNotFoundException() 
{ 
    File.Delete(@"D:\RipWatcher\Bitmap.USF_C.usf"); 
    logWriter= new Mock<LogWriter>().Object; 

    ripfileUploader = new RipFileUploader(logWriter); 

    ripfileUploader.Upload(@"D:\RipWatcher\Bitmap.USF_C.usf",  
    targetDirectory);    
} 

否則你的測試是不確定的,你可以把它扔掉。 另一種可能性是將訪問文件系統的代碼放在單獨的類中,併爲您的RipFileUploader提供模擬實現,以便始終引發異常。