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

如果这个重复,我道歉。 我被赋予了为该方法添加一些覆盖的任务,并被告知模拟私有List属性。 我的问题是: 有没有办法测试私人领域?

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

 public class Class1 { public Class1(List 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 list1 = new List(); public void Do_Complex_Logic() { //list1 will be set with items in it //Now list1 is passed to some other instance } } 

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

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

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

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

那说,你可以尝试:

选项A.
使私有成员内部并为要测试的程序集设置InternalsVisibleTo属性。

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

添加到womp&oleksii已经说过 –

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

一个例子:

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

public List Do_Complex_Logic( List input )

我知道 – 这很简单 ,但是尝试解构一下你的课程并先用测试来重新构建它。

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

‘Do_Complex_Logic’

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

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

私人领域如何做好准备? 如果是通过与存储库的交互,那么您可能会模拟该对象。

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

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