2016-01-29 56 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提供模拟实现,以便始终引发异常。