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

时间:2016-01-29 09:19:05

标签: c# .net unit-testing nunit moq

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

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

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

测试案例......

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

2 个答案:

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

答案 1 :(得分: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提供一个总是抛出异常的测试的模拟实现。