单元测试私有方法

时间:2012-02-07 10:38:13

标签: c# unit-testing

首先,我知道有很多关于这个话题的问题。我已经阅读了大部分内容,但我真的不知道是否缺少适当的OO编程,或者我是否遗漏了某些内容。

所以我有一个类xmlRead,它将XML文件读入某些列表。我想对这门课进行单元测试。我认为最简单的方法是测试addDataToList()。但这是一种私人方法。所以我想知道我是否应该公开它,或者测试公共方法ReadTheXmlFile()。

public class xmlRead 
{
    List<string> ... // A couple of lists that need to filled with data from the XML document
    xmlDocument xDoc = new xmlDocument

    public void ReadTheXmlFile()
    {
        // Find default file, if it doesn't exist, ask user for file through Openfiledialog
        // and open XMLDocument + error handling if XMLdocument is empty etc.
        xDoc.load(filepath);
        takeInXmlData();
    }

    private void takeInXmlData()
    {
        addDataToList(list<string> list1, xmlNode 1);
        // More addDataToList for different lists
        ...
        addDataToList(list<string> list2, xmlNode 2);
    }

    private void addDataToList(list<string> inputList, xmlNode)
    {
         foreach (XmlNode node in xmlDoc.SelectNodes(xmlNode))
         {
             inputList.Add(node.SelectSingleNode("Specific name of node").InnerText);
         }
    }

所以我尽量把事情分开。但这也意味着我的方法addDataToList非常小,但很容易进行单元测试。但我也觉得它也不应该是一种公共方法。我当然可以测试公共方法ReadTheXmlFile(),但是我必须针对错误检测的每个结果制作具体的测试用例,并且在我看来我不会正确地测试数据的实际摄取量到列表中

我是否过度保护,是否应该addDateToList(或takeInXmlData)公开?或者我应该只测试公共方法ReadTheXmlFile,直到我考虑到所有可能的方法?

这感觉就像很多工作一样,这违背了简短的单元测试原则。

PS:我不需要担心我在这里直接加载xDoc的事实,我有一个管理XML文档加载的接口(我可以稍后存根以打破依赖关系)。重点是这里的私人方法。

4 个答案:

答案 0 :(得分:4)

您可以使用InternalsVisibleTo属性允许单元测试查看您的方法,同时将其保密为世界其他地方。

答案 1 :(得分:3)

Reflection允许你调用私有方法并从类外部读取或写入私有字段,但写起来真的很冗长。

在C#4.0中,可以使用动态类型以简洁的方式解决此问题。

如果您可以在单元测试中使用C#4.0,请查看以下文章:

Testing private methods with C# 4.0

一个简单的用法:

public class Service {
    private int Step1() {
        return 1;
    }
}

[TestClass]
public class TransparentObjectTests {
    [TestMethod]
    public void PrivateMethod() {
        dynamic s = new Service().AsTransparentObject();
        Assert.AreEqual(1, s.Step1());
    }
}

答案 2 :(得分:1)

您的addDateToList方法是实施细节。您想要和应该测试的是ReadTheXmlFile方法。你甚至已经发现了应该测试的内容:

  

查找默认文件,如果不存在,请通过Openfiledialog询问用户文件,如果XMLdocument为空,则打开XMLDocument +错误处理等。

  • 测试当发现失败时会发生什么(这听起来像是外部依赖性工作)
  • 测试错误处理
  • 测试XML文档为空
  • 测试属性XML在成功时返回(这将隐式测试私有方法)

关于这个:

  

我当然可以测试公共方法ReadTheXmlFile(),但是我必须为每个错误检测结果制作特定的测试用例,而且在我看来我不会正确测试实际的数据输入到列表。

这就是你应该做的。如果您的方法有多个可能的错误结果,则应测试每个错误结果。它没有比那更简单。大多数框架使用NUnit的TestCase等属性可以轻松实现(多输入/输出测试)。

在旁注中,如果你发现自己非常需要测试私有方法,那么通常很好地指出你的类做了太多东西并且将私有方法的功能提取到外部对象可能是值得考虑的。

答案 3 :(得分:0)

你可以尝试,

打开AssemblyInfo.cs文件。添加此代码,

[assembly: InternalsVisibleTo("Your Test Library Name")]

然后,将私人内容改为内部

您可以在XmlRead类中为内部方法编写测试。