2009-11-06 116 views
16

我有一个名为“Session”的类,它暴露了几个公共方法。我想单元测试这些,但是在生产中我需要控制“会话”对象的实例化,所以将构造委派给SessionManager类并使Session的构造函数成为内部。单元测试一个内部构造函数的类

我理想情况下喜欢从会话管理器中独立地测试会话管理器,它创建会话管理器以证明会话公开的公共接口按预期工作 - 但不能在没有使用的情况下从测试中实例化会话一个SessionManager让我的测试比他们需要的更复杂/更少用处。

处理这个问题的最佳方法是什么?

干杯,

Lenny。

+0

普莱舍清晰起来:是它是受保护的___或内部构造函数? – 2009-11-07 11:25:01

回答

42

没有什么能阻止你从测试的内部简单地让你的代码的内部可见的测试套件,使用InternalsVisibleTo属性:。在集信息,加

[assembly:InternalsVisibleTo("TestSuiteAssembly")] 
+0

这似乎是最简单的方法,所以我想我会用这个来运行。谢谢。 – 2009-11-07 15:10:48

+1

答案真的不完整 - 程序集必须签名才能使其工作。 – Santhos 2014-02-19 14:08:08

+0

@Santhos不是真的... – 2016-10-06 21:30:18

2

你可以只让你的单元测试类继承会话(假设你的测试框架不要求你从一个特定的类继承)。例如,对于NUnit的:

[TestFixture] 
public class SessionTest : Session 
{ 
    public SessionTest() 
     : base() // call protected constructor 
    { 
    } 

    [Test] 
    public void TestSomething() 
    { 
    } 

} 
+1

OP说ctor是内部的,不受保护。 – 2009-11-07 00:40:25

+0

@Rex - 问题的标题说保护,而问题本身说内部。 – 2009-11-07 00:44:14

1

你想用一个产品像TypeMock,这将允许您创建嘲笑(伪造)的类的实例,就像这样:

var myInstance = Isolate.Fake.Instance<Session>(); 
// mock behavior here 
// do assertions here 

您可以创建实例为了记录,还需要使用TypeMock的抽象类。

+3

嘲笑你想测试的同一个班级对我来说没有多大意义,虽然......你会不会测试模拟而不是班级呢? – Svish 2009-11-06 23:47:43

+0

@Svish,你是正确的,伪造的行为没有用,但它也可以创建实例并解决可访问性问题:Isolate.Fake.Instance (Members.CallOriginal)。这样你就有了一个类的实际实例,其构造函数是无法访问的。 免责声明 - 我在Typemock工作。 – Elisha 2009-11-07 12:45:50

2

另外,作为一种解决方法,你可以只创建一个从会话继承,并公开公共构造一个TestSession。在你的单元测试中,你使用TestSession,它基本上和最初的Session对象一样。

public class TestSession : Session 
{ 

    public TestSession() : base() 
    { 

    } 

} 
1

我会质疑使会话类构造函数内部的价值。

通常这意味着你正试图阻止其他开发者使用你的类。也许最好交流这个特定的应用程序如何工作,以及为什么你只想从会话管理器访问会话?

+0

我已经看到它使用工厂模型做了很多工作,你可能想要强制该类只在一个地方创建或销毁,但其他人可以引用它并使用它。 – 2009-11-06 23:48:21

+0

我也看到了很多:)我只是看不出它是如何增加任何价值的。当您想要扩展或测试时,它就会导致问题 - 就像伦纳德现在正在经历的一样。 MS是这方面最糟糕的犯罪分子之一,有很多内部课程有时会有用,但我们无法访问它们! Frustraing! – 2009-11-06 23:51:57

+5

作为一个曾经是API消费者的人,并且非常沮丧,就像你想知道MS为什么会在内部做许多事情,受到保护等等。现在我主要做API开发,而我的东西被其他开发人员使用。我花了很多时间来清理别人的麻烦,因为他们用自己内部的东西来解决问题。有时,期望能够正确使用我们编写的每一段代码是不现实的。 – 2009-11-07 00:01:15

0

如果你可以用“受保护的内部”构造离开,那么,假设你的测试是在不同的组件,你可以InternalsVisibleTo属性添加到您的“待测试组装”。这将使你的测试,看看内部成员将要测试的组装”。

更新 出于某种原因,我读了你的构造是受保护的,它使你在一个很好的位置,已经是内部使用该属性