2011-02-25 180 views
1

首先我很抱歉如果问题已被问到,但我没有找到像我的任何人(但我认为这是一个相当普遍的问题) 所以我试图做一些单元测试,和第一个已经成问题了。访问私人字段

我必须测试我的类的构造函数,在构造函数中我设置了一个私有字段的实例。那么如何测试这个PRIVATE字段是否不为空呢? (因为我想的是,我有什么测试) - >测试:

public BUDGET_MANAGER() 
    { 
     this.budget_provider = new BUDGET_PROVIDER(); 
    } 

- >测试Mehod:

[TestMethod()] 
    public void BUDGET_MANAGERConstructorTest1() 
    { 
     BUDGET_MANAGER target = new BUDGET_MANAGER();  
     Assert.IsNotNull(??,"the provider is not instancied"); 

    } 

我该怎么办呢?感谢您的帮助,我迷上了单元测试。

+1

参见:http://msdn.microsoft.com/en-us/library /0tke9fxk.aspx(尽管你必须使字段“内部”而不是“private”,这可能不是你想要的。) – 2011-02-25 22:31:00

+0

[单元测试和检查私有变量值](http:/ /stackoverflow.com/questions/1093020/unit-testing-and-checking-private-variable-value) – 2011-02-25 22:33:08

回答

4

在你的单元测试中,你真的不应该测试任何对于一个类是私有的东西。私有的,内部唯一的已知成员是类的实现的一部分,而不是其公开的(已测试的)功能的一部分。

基本上,把这个类的外部可见的成员想象成它的“契约”。这就定义了它的实际类型,其他所见。这就是被测试的功能。由于很好的理由,内部(私人)成员在班级之外并不知道,不同的班级可以以不同的私人成员以不同的方式实施相同的“合同”(或界面)。

您正在测试的是可见功能,合同或界面。

+0

好,那么没有什么可以测试我的情况? – bAN 2011-02-25 22:35:12

+0

@bAN:取决于班级。如果“类型”(接口,隐式或显式)与“类”(实现)紧密结合,那么单元测试表明可能需要重新思考和重新考虑。将接口的概念与类分开,测试将变得更加明显。 (顺便说一句,这是一个积极的测试结果...确定有关可能需要更改的类的信息。)但是,回答是,没有什么可以测试私有成员。只有公共功能。 – David 2011-02-25 22:38:16

2

单元测试应该不是检查私人数据。他们应该测试你的类的接口定义的行为是否工作,与任何实现细节无关。

典型的测试会调用构造函数,然后调用公共属性或方法并检查结果是否如预期的那样。以这种方式进行测试意味着如果稍后将实现更改为(例如)仅在需要时才构造BudgetProvider,那么所有测试仍然可以工作。诸如私有成员是否为空的实现细节与你的类的客户无关,因此不需要在你的单元测试中进行测试。

+0

我想你的意思是单元测试应该*不*检查私人数据,不是?如果是的话,同意。 – Paul 2011-02-25 22:30:51

+0

@保罗:是的,谢谢!这就是我的意思。 – 2011-02-25 22:32:49

1

如果您使用mstest,请右键单击原始类,然后按创建测试访问器,选择您的测试项目。然后使用访问器测试此条件(应显示为intellisense)。

虽然我不确定它是一个非常好的主意,正如其他海报所说的那样。你会让实施变得更加困难。

1

你不应该真的测试你的类的任何私有变量。

为什么你想测试构造函数本身?如果有一些逻辑,测试它是有意义的。例如 - 如果给定的参数是正确的,并且在创建对象之前进行验证,则只构造该对象。否则,构建该对象并验证其行为如预期。据推测,如果构造函数工作不正确,对象的行为也将不正确。

也抵制暴露专用字段作为属性的诱惑,以验证它们是否在构造函数中正确设置。

+0

好的谢谢,并在此构造函数中设置值(构造函数参数)给私人budget_provider的情况下,我是否模拟了budget_provider以测试是否在budget_provider上调用了一个集合? – bAN 2011-02-25 22:42:23

+0

是的。这是一个非常好的方法 - 测试类和它的依赖关系(budget_provider)的交互。您可以根据对象的状态检查预期的交互是否发生。 – mfloryan 2011-02-26 11:57:47

0

其他人提到你使用单元测试时不应该做的事情。

我会试着找到一种方法,做你想做的(你还需要测试你的构造函数):

public BUDGET_MANAGER() 
{ 
    try 
    { 
     this.budget_provider = new BUDGET_PROVIDER(); 
    } 
    catch {} 

    if (this.budget_provider == null) 
     throw new NullReferenceException("Budget provider is null !"); 
} 
+0

没有冒犯,但这是荒谬的。除非CLR被破坏,否则“new”不能返回null。例如:给我写一个测试,说明抛出这个异常。 – bryanbcook 2011-02-26 13:35:37

+0

默认情况下,您应该将代码块视为“伪代码”。如您所见,原始问题也存在同样的问题,但我们假设他已将案例简介为可读性。如果它让你开心,我在'new'关键字上添加了一个'try/catch'。 – Xaqron 2011-02-26 15:22:28