我有一个名为“Session”的类,它暴露了几个公共方法。我想对这些进行单元测试,但是在生产中我需要控制“Session”对象的实例化,因此将构造委托给SessionManager类并使Session的构造函数内部化。
理想情况下,我希望将Session类与SessionManager隔离开来,它创建它/它们来证明Session公开的公共接口按预期工作 - 但不能在不使用a的情况下从测试中实例化Session SessionManager使我的测试比他们需要的更复杂/更少。
处理此问题的最佳方法是什么?
干杯,
莱尼。
答案 0 :(得分:45)
没有什么可以阻止你测试内部。通过使用InternalsVisibleTo属性,只需使代码的内部对测试套件可见:在AssemblyInfo中,添加
[assembly:InternalsVisibleTo("TestSuiteAssembly")]
答案 1 :(得分:3)
您可以让您的单元测试类继承自Session(假设您的测试框架不要求您继承特定的类)。例如,使用NUnit:
[TestFixture]
public class SessionTest : Session
{
public SessionTest()
: base() // call protected constructor
{
}
[Test]
public void TestSomething()
{
}
}
答案 2 :(得分:2)
或者,作为一种变通方法,您可以创建一个继承自Session的TestSession并公开一个公共构造函数。在单元测试中,然后使用TestSession,它基本上与原始Session对象相同。
public class TestSession : Session
{
public TestSession() : base()
{
}
}
答案 3 :(得分:1)
您希望使用像TypeMock这样的产品,它允许您创建类的模拟(伪造)实例,如下所示:
var myInstance = Isolate.Fake.Instance<Session>();
// mock behavior here
// do assertions here
您也可以使用TypeMock为记录创建抽象类的实例。
答案 4 :(得分:1)
我会质疑使会话类构造函数成为内部的价值。
通常这意味着您试图阻止其他开发人员使用您的类。也许最好是沟通这个特定的应用程序如何工作以及为什么你只想从会话管理器访问会话?
答案 5 :(得分:0)
如果您可以使用“protected internal”构造函数,那么,假设您的测试位于不同的程序集中,您可以将InternalsVisibleTo属性添加到“待测试程序集”中。这将允许您的测试查看待测试组件的内部成员“。
<强>更新强> 出于某种原因,我读到你的构造函数受到保护。它已经是内部的,因此您可以很好地使用该属性。
答案 6 :(得分:0)
对于.Net Core
,您可以修改.csproj
...
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
<_Parameter1>$(AssemblyName).Tests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
...
它将使内部内容对您的测试项目可见。