Rhino Mocks测试文件系统io

本文关键字:io 文件系统 测试 Mocks Rhino | 更新日期: 2023-09-27 18:19:27

我有一个应用程序,它获取一个文件字典(文件类型和文件名列表),并将文件从原始目录复制到另一个位置。我已经有了复制过程的基本代码,但我需要做一些单元测试,以便它尽可能健壮。

我有一个正在使用的包装类,这样我就可以测试是否按预期调用了System.IO方法,但我很难弄清楚如何形成测试,因为代码中有foreach和switch语句。下面的示例代码:

private IFileSystemIO _f;

public CopyFilesToDestination(IFileSystemIO f){
    _f = f;
}

public void Cpy_Files(Dictionary<string, List<string>> files)
{
// get a list of the file types in the directory
var listOfFileTypes = new List<string>(files.Keys);
foreach (var fileType in listOfFileTypes){
    var fileList = files[fileType].ToList();
    foreach  (var file in fileList){
        switch(fileType){
            case ".txt":
                _f.Copy(file, @"c:'destination'text");
                break;
            case ".dat":
                _.Copy(file, @"c:'destination'data");
                break;
        }
    }
}
}

为了测试以上内容,我曾想过我会使用一个模拟字典对象,设置一个文件类型和路径列表:

public virtual Dictionary<string, List<string>> FakeFiles(){
    return fakeDictionary = new Dictionary<string, List<string>>(){
        {".txt",  new List<string>(){
            "c:'test'file1.txt",
                "c:'test'file2.txt"
            }
        },
        {".dat", new List<string>(){
                "c:'test'file1.dat",
                "c:'test'file2.dat"
            }
        };
    }
}

我提出的第一个测试看起来是这样的:

[Test]
public void Should_Copy_Text_Files(){
    var dictionary = new FakeDictionary().FakeFiles();
    var mockObject = MockRepository.GenerateMock<IFileSystemIO>();
    var systemUnderTest = new CopyFileToDestination(mockObject);
    systemUnderTest.Cpy_Files(dictionary);
    // I think this means "test the operation, don't check the values in the arguments"      but I also think I'm wrong
    mockObject.AssertWasCalled(f => f.Copy("something", "something"), o =>     o.IgnoreArguments());
}

我的第一个问题是:如何测试特定的文件类型,如".txt"?那么我该如何测试循环呢?我知道我只有两个条目,我可以利用它来形成测试吗?怎样

我想我可能已经接近解决方案了,但我已经没有时间/耐心去寻找了。非常感谢您的帮助。谢谢Jim

Rhino Mocks测试文件系统io

我尝试使用Roberts解决方案,但正如我所说,我有太多不同的文件类型,无法单独设置每个测试用例。我尝试的下一件事是设置一个TestCaseSource,但每次我为此运行测试时,它都会将测试标记为忽略:

[Test, TestCaseSource(typeof(FakeDictionary), "TestFiles")]
public void Cpy_Files_ShouldCopyAllFilesInDictionary(string extension, string fielName)    {
    // Arrange
    var mockObject = MockRepository.GenerateMock<IFileSystemIO>();
    var systemUnderTest = new CopyFileToDestination(mockObject);
    // Act
    systemUnderTest.Cpy_Files(dictionary);
    // Assert
    mockObject.AssertWasCalled(f => f.Copy(extension, fileName));
}

数据来源如下:

public static Dictionary<string, string> TestFiles{
    get
    {
        return new Dictionary<string, string>()
            {
                {".txt",
                "C:''test''test1.txt"},
                {".txt",
                "c:''test''test2.txt"}
            };
    }
} 

我最终得出的是使用Rhino中的时间重复选项,非常简单:

[Test]
public void Cpy_Files_ShouldCopyAllFilesInDictionary(){
    // Arrange
    var mockObject = MockRepository.GenerateMock<IFileSystemIO>();
    var systemUnderTest = new CopyFileToDestination(mockObject);
    // Act
    systemUnderTest.Cpy_Files(dictionary);
    // Assert
    // I know how many objects are in my fake dictionary so I set the times to repeat as a const
    const int timesToRepeat = 2;
    // now I just set the values below. I am not testing file names so the test will ignore arguments
    mockObject.AssertWasCalled(f => f.Copy("",""), options => options.Repeat.Times(timesToRepeat).IgnoreArguments());
}

我希望这能帮助其他有类似问题的人。

我会尝试使用TestCase属性:

[TestCase(".txt", "c:'test'file1.txt")]
[TestCase(".txt", "c:'test'file2.txt")]
[TestCase(".dat", "c:'test'file1.dat")]
[TestCase(".dat", "c:'test'file2.dat")]
public void Should_Copy_Text_Files(string extension, string fileName){
    var dictionary = new FakeDictionary().FakeFiles();
    var mockObject = MockRepository.GenerateMock<IFileSystemIO>();
    var systemUnderTest = new CopyFileToDestination(mockObject);
    systemUnderTest.Cpy_Files(dictionary);
    mockObject.AssertWasCalled(f => f.Copy(extension, fileName));
}

这将分别为每个TestCase属性运行测试,并将其包含的参数传递到测试方法中。这样,您就可以测试字典中的每个项是否是"复制的",而无需在同一测试中使用多个断言。