对静态类进行单元测试(理论问题)

发布于 2024-12-03 08:10:28 字数 119 浏览 3 评论 0原文

我知道什么时候可以使用静态类,但我的简单问题是:

当我们对具有静态类的代码进行单元测试时,是否存在大问题?

使用常规实例类更好吗?

有一些问题讨论了这一点,但所有问题都基于特定情况。

I know when it is ok to use a static class, but my simple question is:

Is there a big problem when we're unit-testing our code that has a static class?

Is better to use a regular instance class?

There are some questions that talk about this, but all are based in particular cases.

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

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

发布评论

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

评论(1

萌面超妹 2024-12-10 08:10:28

我所做的是将现有的静态类用作接缝,并在不同的名称空间中提供替代实现。这意味着您可以通过尽可能少的更改来测试代码——只需更改名称空间。通常,我必须这样做才能绕过 C# 文件系统操作 - File.Exists 等。

假设您的方法基本上是这样做的:

using System.IO;

public void SomeMethod()
{
    ...
    if(File.Exists(myFile))
    {
        ...
    }
    ...
}

那么我将用替代方案替换 File 的实现。替代实现应该消除任何现有方法,并在幕后调用委托实现 - 例如

namespace IO.Abstractions 
{     
    public static class File
    {         
        public static Func<string, string, string> ExistsImpl =
                                                      System.IO.File.Exists;

        public static string Exists(string path)
        {             
            return ExistsImpl (path);
        }
    }
} 

,然后我将修改原始代码,以便它使用新的命名空间:

using IO.Abstractions;

public void SomeMethod()
{
    ...
    if(File.Exists(myFile))
    {
        ...
    }
    ...
}

然后,在您的测试中,您可以提供替代方案File.Exists 行为的实现,类似于:

[Test]
public void SomeTest()
{
    // arrange
    ...
    File.ExistsImpl = (path) => true; // to just default to true for every call
    ...

    // act
    someClass.SomeMethod();

    // then assert
    ...
}

我最近写了一篇博客,其中包含更多详细信息这里

What I do is take the existing static class use as a seam, and provide an alternative implementation in a different namespace. This means that you can get the code under test with as few changes as possible -- just namespace changes. Typically I've had to do this to get round C# filesystem ops -- File.Exists etc.

Say your method basically does this:

using System.IO;

public void SomeMethod()
{
    ...
    if(File.Exists(myFile))
    {
        ...
    }
    ...
}

then I'd replace that implementation of File with an alternative. The alterntive implementation should stub out any existing methods, and make calls to delegate implementations under the covers -- e.g.

namespace IO.Abstractions 
{     
    public static class File
    {         
        public static Func<string, string, string> ExistsImpl =
                                                      System.IO.File.Exists;

        public static string Exists(string path)
        {             
            return ExistsImpl (path);
        }
    }
} 

Then I'd modify the original code so that it uses the new namespace:

using IO.Abstractions;

public void SomeMethod()
{
    ...
    if(File.Exists(myFile))
    {
        ...
    }
    ...
}

Then, in your test, you can just provide an alternative implementation of the behaviour for File.Exists, something like:

[Test]
public void SomeTest()
{
    // arrange
    ...
    File.ExistsImpl = (path) => true; // to just default to true for every call
    ...

    // act
    someClass.SomeMethod();

    // then assert
    ...
}

I wrote a blog with some more details recently here.

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