处理单元测试 C# 中的预期异常

Handling Expected exception in Unit Test C#

我写了一个检查文件路径的测试用例。在那个测试用例中,我使用了 Expected exception,然后我想知道如果该方法不会抛出文件未找到异常会发生什么。

比如我运行另一个系统中的测试用例如果系统中存在给定的文件路径,测试就会失败。但它不应该,测试用例应该总是通过。

如何处理这种情况,因为单元测试不依赖于任何示例不应该依赖于机器?

测试用例...

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);        
    }          
}

如果你想要确定性的结果,你必须确保该文件不存在于任何机器上。

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);            
}

否则你的测试不是确定性的,你可以把它扔掉。 另一种可能性是将访问文件系统的代码放在单独的 class 中,并为您的 RipFileUploader 提供一个模拟实现,以进行始终抛出异常的测试。

如果您希望这样的方法是可测试的并且独立于它运行的机器 - 您不应该直接使用 FileDirectory 类。

取而代之的是从您需要的所有 类 中提取具有方法的接口,编写该接口的实现,它使用 FileDirectory 类.[=16 的方法=]

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);            
}