在C#中测试/注入私有字段的好习惯是什么?

时间:2012-07-19 16:48:23

标签: c# unit-testing tdd code-coverage

如果这是重复,我道歉。我被赋予了为该方法添加一些覆盖范围的任务,并被告知要模拟私有List<string>属性。我的问题是:有没有办法测试私有字段?

我找到的解决方案是添加新的构造函数,只是为了注入这个私有列表。我不确定这是否正确,所以任何帮助都将受到高度赞赏。

public class Class1
{
    public Class1(List<string> list)//This is just for Unit Testing 
    {
        list1 = list;
    }


    private readonly InjectRepository _repository;
    //
    public Class1(InjectRepository repository)//This is the actual constructor
    {
        _repository = repository;
    }

    private List<string> list1 = new List<string>();

    public void Do_Complex_Logic()
    {
       //list1 will be set with items in it
       //Now list1 is passed to some other instance
    }
}

6 个答案:

答案 0 :(得分:4)

类的私有逻辑应该在其行为的公共表达中可见。换句话说,理论上说,根本不需要测试私有字段。

无法直接测试私有字段;毕竟他们是私人的。如果您真的认为需要测试私有字段,那么我建议将其改为内部,并通过[InternalsVisibleTo]属性将其公开给您的单元测试程序集。

话虽如此,有些框架允许这样的事情,例如TypeMock

答案 1 :(得分:4)

不要测试私有字段或方法。测试合同的行为 - 公共或内部方法。

那说,你可以试试:

选项A
为正在测试的程序集创建私有成员内部并设置InternalsVisibleTo属性。

选项B
编写一个包装类,将私有字段/方法包装到公共字段/方法中。这种方法的好处是您不需要将私有方法设置为内部方法。缺点是,对于每个私有方法,您将拥有一个包装器公共方法。所以方法的数量可能会翻倍。

答案 2 :(得分:3)

添加到什么womp&amp; oleksii已经说过 -

您希望/需要测试私有方法的事实是一个标志(气味?),您的设计可能不正确。这是TDD(以及我个人最喜欢的)的积极副作用之一。

一个例子:

我在这里并不完全了解你的域名,但是一个简单的改变可能是,而不是Do_Complex_Logic没有参数,你可以让它采取并返回List<string>

public List<string> Do_Complex_Logic( List<string> input )

我知道 - 它是简单的,但尝试解构一下你的类,并先用测试重新构建它。

答案 3 :(得分:1)

我不同意其他答案;但在这种情况下,我认为最合适的事情是 - 给出你的代码;是改变

的签名

'Do_Complex_Logic'

真正的问题是你正在处理List1的'状态'。如果将List1传递给Do_Complex_Logic - 您的问题基本上已得到解决。你的评论说'Do_Complex_Logic'将(可能)在List1上做一些工作,然后将其传递给其他东西,对吗?

让Do_Complex_Logic获取List并返回List。现在很容易测试。您可以“注入依赖项”,而不是依赖于在类中正确设置List1的状态。

答案 4 :(得分:1)

首先如何准备私人领域?如果是通过与存储库的交互,那么你可以模拟该对象。

这样做的一种方法是通过界面与您的存储库进行交互(让我们称之为IInjectRepository而不是具体的实体,然后使用类似Moq的东西(或其中一个)在设置测试时,通过模拟存储库填充您的数据。在您调用Do_Complex_Logic后,我假设您有一种询问实体的方式,以便您了解它已经完成了你的期望。这样你就可以避免/减轻添加仅用于测试的方法和类。

答案 5 :(得分:0)

您可以在相关问题的回答https://stackoverflow.com/a/3376157/1523402中使用反思。 我不知道私人访问者是否也适用于私人领域。但他们(至少)帮助私人方法(见http://msdn.microsoft.com/en-us/library/ms184807%28v=vs.80%29.aspx)。