使用内部构造函数对类进行单元测试

发布于 2024-08-10 12:56:15 字数 335 浏览 5 评论 0原文

我有一个名为“Session”的类,它公开了几个公共方法。我想对这些进行单元测试,但是在生产中我需要控制“Session”对象的实例化,因此将构造委托给 SessionManager 类,并将 Session 的构造函数设为内部。

理想情况下,我希望与 SessionManager 隔离地测试 Session 类,SessionManager 创建它/它们,以证明 Session 公开的公共接口按预期工作 - 但如果不使用 SessionManager 就无法从测试中实例化 Session ,这使得我的测试比它们需要的更复杂/没那么有用。

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

干杯,

莱尼。

I have a class called "Session" which exposes several public methods. I'd like to Unit Test these, however in production I need to control instantiation of "Session" objects, so delegate construction to to a SessionManager class and have made the Session's constructor internal.

I'd ideally like to test the Session class in isolation from the SessionManager which creates it/them to prove that the public interfaces exposed by the Session work as expected - but can't instantiate a Session from a test without using a SessionManager making my tests more complicated/less useful than they need to be.

What's the best way to deal with this?

Cheers,

Lenny.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

小镇女孩 2024-08-17 12:56:16

没有什么可以阻止您测试内部结构。只需使用 InternalsVisibleTo 属性,使代码的内部结构对测试套件可见:在 AssemblyInfo 中,添加

[assembly:InternalsVisibleTo("TestSuiteAssembly")]

Nothing prevents you from testing internals. Simply make the internals of your code visible to the test suite, by using the InternalsVisibleTo attribute: in the AssemblyInfo, add

[assembly:InternalsVisibleTo("TestSuiteAssembly")]
心舞飞扬 2024-08-17 12:56:16

您可以让您的单元测试类从 Session 继承(假设您的测试框架不要求您从特定的类继承)。例如,使用 NUnit :

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

    [Test]
    public void TestSomething()
    {
    }

}

You could just make your unit test class inherit from Session (assuming your test framework doesn't require that you inherit from a specific class). For instance, with NUnit :

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

    [Test]
    public void TestSomething()
    {
    }

}
苹果你个爱泡泡 2024-08-17 12:56:16

或者,作为一种解决方法,您可以创建一个继承自 Session 并公开公共构造函数的 TestSession。然后在单元测试中使用 TestSession,它的作用基本上与原始 Session 对象相同。

public class TestSession : Session
{

   public TestSession() : base()
   {

   }

}

Alternatively, as a workaround, you could just create a TestSession that inherits from Session and exposes a public constructor. Inside your unit-test you then use the TestSession which basically does the same as the original Session object.

public class TestSession : Session
{

   public TestSession() : base()
   {

   }

}
夜血缘 2024-08-17 12:56:16

您想要使用像 TypeMock 这样的产品,它允许您创建模拟(伪造)的实例类,如下所示:

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

您也可以使用 TypeMock 创建抽象类的实例,以供记录。

You want to use a product like TypeMock, which will allow you to create mocked (faked) instances of classes, like this:

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

You can create instances of abstract classes with TypeMock as well, for the record.

挽你眉间 2024-08-17 12:56:16

我会质疑将会话类构造函数设置为内部的价值。

一般来说,这意味着您试图阻止其他开发人员使用您的类。也许更好的方式是传达应用程序的这个特定部分如何工作以及为什么您只想从会话管理器访问会话?

I would question the value of making the session class constructor internal.

Generally this implies you are trying to stop other developers from using your class. Maybe it would be better to communicate how this particular piece of the application works and why you would only want to access the session from the session manager?

自控 2024-08-17 12:56:16

对于.Net Core,您可以修改.csproj

...
<ItemGroup>
    <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
        <_Parameter1>$(AssemblyName).Tests</_Parameter1>
    </AssemblyAttribute>
</ItemGroup>
...

它将使内部内容对您的测试项目可见。

For .Net Core you can modify .csproj

...
<ItemGroup>
    <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
        <_Parameter1>$(AssemblyName).Tests</_Parameter1>
    </AssemblyAttribute>
</ItemGroup>
...

It will make internal stuff visible for your test project.

深海少女心 2024-08-17 12:56:16

如果您可以保留“受保护的内部”构造函数,那么假设您的测试位于不同的程序集中,您可以将 InternalsVisibleTo 属性添加到“待测试程序集”中。这将使您的测试能够看到待测试程序集的内部成员”。

更新
出于某种原因,我读到您的构造函数受到保护。它已经是内部的,因此您可以很好地使用该属性。

If you can leave with "protected internal" constructor, then, assuming that your tests are in different assembly, you can add InternalsVisibleTo attribute to your "to-be-tested-assembly". This would allow your tests to see internal members of to-be-tested-assembly".

Update
For some reason I read that your constructor was protected. It is already internal so you are in a good position to use that attribute.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文