简体   繁体   English

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

[英]Handling Expected exception in Unit Test C#

I wrote a test case for checking file path. 我写了一个测试用例来检查文件路径。 In that test case I used Expected exception, then I want to know what happen if the method would not throw the file not found exception. 在该测试用例中,我使用了Expected异常,然后我想知道如果该方法不抛出文件未找到异常会发生什么情况。

For example, I run the test case in another system if the given file path exists in the system, the test will go to fail. 例如,如果给定的文件路径存在于系统中,那么我将在另一个系统中运行测试用例,则测试将失败。 But it should not be, the test case should be pass always. 但事实并非如此,测试案例应始终通过。

How to handle that situation because the Unit test is not dependent anything example should not depend on machine? 由于单元测试不依赖任何实例,该如何处理这种情况不应该依赖机器?

Test case... 测试用例...

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

Method.. 方法..

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

If you want such a method to be testable and independent from machine it runs on - you should not use File and Directory classes directly. 如果您希望这种方法是可测试的并且独立于它运行的机器,则不应直接使用FileDirectory类。

Instead extract interface having methods from all classes you need, write an implementation of this interface which uses methods of File and Directory classes. 取而代之的是从您需要的所有类中提取具有方法的接口,编写此接口的实现,该实现使用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))
    {
        ....
    }
}

In working environnment you will use this implementation, and in testing environment you have to create mocking object implementing this interface. 在工作环境中,您将使用此实现,而在测试环境中,您必须创建实现此接口的模拟对象。 So you can setup this mock in any way you need. 因此,您可以按照需要的任何方式设置此模拟。

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

If you want deterministic Results, you have to make sure that the file does not exist on any machine. 如果需要确定的结果,则必须确保该文件在任何计算机上都不存在。

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

Otherwise your test is not deterministic and you can just throw it away. 否则,您的测试是不确定的,您可以将其丢弃。 Another possibility would be to put the Code that accesses the file system in a separate class and give your RipFileUploader a mock implementation for the test that always throws the exception. 另一种可能性是将访问文件系统的代码放在单独的类中,并为您的RipFileUploader提供一个总是执行该异常的测试的模拟实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM