如何为读取文件并将文件路径作为参数的方法创建单元测试

时间:2016-06-13 16:04:24

标签: c# unit-testing nunit

我知道这可能很容易,但由于我刚刚开始学习单元测试,我对所有可能性都感到困惑。

我有这个非常简单的方法,它应该从文件中读取整数数字(条件是该文件只包含整数,每个都存储在一个新行中)。

public static IEnumerable<int> ReadIntegers(string file)
{
    using (var stream = File.OpenText(file))
    {
        string line;
        while ((line = stream.ReadLine()) != null)
        {
            yield return int.Parse(line);
        }
    }
}

在我继续之前,请不要建议我重构方法,我已经找到它并且我想学习如何为这个特定的输入参数和输出值编写单元测试。

我发现了另一个话题,有人建议在测试用例中创建测试文件,而不是尝试将预期与实际结果进行比较,如下所示:

 [Test]
 public void ShouldValidateReadingOfTheFile()
 {
     string path = @"E:\TestFile.txt";
     using (var sw = File.AppendText(path))
     {
         sw.WriteLine(1);
         sw.WriteLine(100);
     }
     var expected = new List<int>() { 1, 100 };
     var actual = TestProject.Merge.ReadIntegersFromFile(path);
     Assert.IsTrue(expected.SequenceEqual(actual));
 }

我想问你这是一个不好的做法吗?你有不同的方法吗?关于这种方法的不同测试是否有任何其他想法。谢谢!

3 个答案:

答案 0 :(得分:3)

我认为你可以这样做unit-testing,但我建议你也测试一下特殊情况。

E.g。

  • null作为文件名
  • 一个空文件
  • 包含许多条目的大文件
  • 不仅有整数的文件

创建测试文件是一种常见做法。

答案 1 :(得分:2)

我会在2

中拆分方法
public static IEnumerable<int> ReadIntegers(Stream file)
{
    ///... your code here
}

public static IEnumerable<int> ReadIntegers(string file)
{
     var stream = File.OpenText(file);
     return ReadIntegers(stream)
}

并且单元测试自己:

[Test]
public void ShouldValidateReadingOfTheFile()
{
    string stream = new MemoryStream();
    using (var sw = StreamWiter(stream))
    {
        sw.WriteLine(1);
        sw.WriteLine(100);
    }
    var expected = new List<int>() { 1, 100 };
    var actual = TestProject.Merge.ReadIntegersFromFile(path);
    Assert.IsTrue(expected.SequenceEqual(actual));
}

我所做的是用MemoryStream包裹StreamWriter所以很容易写出填充我想要的值的行。应该这样做。

然后,您可以使用相同的策略来测试所有其他案例并制作这样的帮助:

private Stream GetStream(IEnumerable<int> values)
{
    string stream = new MemoryStream();
    using (var sw = StreamWiter(stream))
    {
        foreach(int i in values)
            sw.WriteLine(i);
    }

    return stream;
}

或类似的东西。使用这种方法,您可以对执行实际工作的方法(具有Stream参数的方法)进行所需的所有测试,如果仍需要测试文件的开放(string到{{然后你可以在你的项目中使用一个测试文件,这样你就可以对它进行测试,虽然我没有看到它的重点,因为你正在测试框架的工作能力对于文件,如果文件名来自您的代码,那么更好的方法是测试文件名生成代码。希望这可以帮助。快乐的编码

答案 2 :(得分:1)

您可以使用typemock框架对方法进行单元测试而不进行重构,以下是代码示例:

[TestMethod, Isolated]
public void ShouldValidateReadingOfTheFile()
{
    var fileContents = 
@"1
100";
    StreamReader reader = new StreamReader(
        new MemoryStream(Encoding.ASCII.GetBytes(fileContents)));

    Isolate.WhenCalled(() => File.OpenText("fake")).WillReturn(reader);

    var result = Class1.ReadIntegers("fake").ToArray();

    var resList = new int[] {1, 100};
    CollectionAssert.AreEquivalent(resList, result);
}

我希望这有助于您更好地了解单元测试。