使用File.Exists进行单元测试功能

时间:2017-07-27 15:03:50

标签: c# unit-testing mocking

我如何对这类功能进行单元测试?当然,我无法创建真实文件,但我无法对示例类和 Func 进行任何更改,以便于测试。

正如我发现的那样,使用流行的免费框架(如moq)无法模拟静态Exists。我发现了一些模拟文件系统的框架,比如System.IO.Abstractions(https://github.com/tathamoddie/System.IO.Abstractions),但在我发现的所有样本中,方法(如CreateDirectory等 - 这里Exists)都是通过模拟调用的对象,我不知道如何使它适应这种方法(如果可能的话)。

public class Example
{
    public int Func()
    {
        if(System.IO.File.Exists("some hard-coded path"))
        {
            return 1;
        }
        else
        {
            return 2
        }
    }
}

3 个答案:

答案 0 :(得分:5)

如何创建FileWrapper类并将其作为测试中的依赖项传递?

public class Example
{
    private IFileWrapper _fileWrapper;

    public Example()
        : this(new FileWrapper())
    {
    }    

    public Example(IFileWrapper fileWrapper)
    {
        _fileWrapper = fileWrapper;
    }

    public int Func()
    {
        if (_fileWrapper.Exists("some path")
        {
            // etc
        }
    }
}

然后将FileWrapper定义为:

internal class FileWrapper : IFileWrapper
{
    public bool Exists(string path)
    {
        return File.Exists(path);
    }
}

和界面IFileWrapper为:

public interface IFileWrapper
{
    bool Exists(string path);
}

然后你的测试可以创建IFileWrapper的模拟并将其传递到你正在测试的类中(在这里使用Moq):

[TestMethod]
public void Func_ShouldCheckFileExists()
{
    // Arrange
    var mockFileWrapper = new Mock<IFileWrapper>();
    mockFileWrapper.Setup(_ => _.Exists(It.IsAny<string>())).Returns(true);

    var example = new Example(mockFileWrapper.Object);

    // Act
    int returnValue = example.Func("test path");

    // Assert
    Assert.Equals(returnValue, 1);
}

它还有一些工作要做,但你可以建立一个包含这些包装器的库,并在你的代码库中重用它们。

如果您真的无法修改代码,那么查看Microsoft的Moles项目或更新的Fakes项目可能会对您有所帮助。

答案 1 :(得分:0)

可能,我重新邀请了模拟轮,但下面的简单代码对我有用,它在我的许多单元测试中使用: 我在单元测试中使用 public bool isUT == true ,否则== false ; bool函数,与问题中的Example类似,是

public bool IsFileExist(string pathFile) => x.Exists(pathFile);

使用上面的 FileWrapper

internal class FileExist : IFileWrapper
{
    public bool Exists(string path) => File.Exists(path);
}
public interface IFileWrapper
{
    bool Exists(string path);
}

受保护的IFileWrapper x; 在业务运行中是 null ,或者从单元测试注入依赖项并引用模拟类

public class mock : FileOp, IFileWrapper
{
    private string myPath { get; set; }

    internal mock(string myPath = "")
    {
        base.x = this;
        this.myPath = myPath;
    }

    public bool Exists(string path) => path == myPath;
}

当myPath包含与请求中相同的字符串时,它会模拟现有文件,否则IsFileExist将返回false。

答案 2 :(得分:-1)

以非常简单的方式完成

Assert.IsTrue(File.Exists(FILENAME));