asp.net 如何正确地设计类,使内部逻辑是可单元测试的?

uinbv5nw  于 2023-11-20  发布在  .NET
关注(0)|答案(1)|浏览(123)

我正在努力弄清楚如何在一个大型代码库中正确地设计代码,以便内部逻辑可以轻松测试。这里有一个虚构的例子:

public class SomeService
{
    public SomeService(){}
    
    public DoThingA(bool flagA)
    {
        // lots of logic 
        ...

        // eventually get some object, either through a request or some other way
        ObjectA response = makeSomeHttpRequest();
        
        // get some value based on the object and some other fields
        var url = GenerateUrl(response, flagA);

        // more logic
    }
    
    private string GenerateUrl(ObjectA response, bool flagA)
    {
        if (response.field1 == "foo" && flagA)
        {
            return "plugh.com";
            
        }
        else if (response.field1 == "bar")
        {
            return "xyzzy.com";
        }
        else
        {
            return "thud.com";
        }
    }
}

字符串
如果我想写一个单元测试来处理GenerateUrl的逻辑,我该怎么做?

  • 通过调用DoThingA来计算GenerateUrl的响应可能并不容易,所以我不想这样做
  • GenerateUrl的逻辑相对较小,并且是DoThingA()的内部逻辑,因此我不希望仅为了测试而公开它
  • 我可以将GenerateUrl的逻辑移动到SomeService所依赖的它自己的类中,但是在一个大型代码库中,这将导致数百个非常小的类,这些类可能只有几行逻辑

那么,什么是正确的方法来构造它,以便我可以测试一些内部逻辑呢?也许GenerateUrl实际上是一些验证逻辑,或者只是我想要进行单元测试的任何单个函数。

olqngx59

olqngx591#

当涉及到测试私有/内部逻辑时,我已经看到了很多关于这个问题的观点和方法。通常人们可能会听到只测试公共API,因为它是一个将对外部组件可用的API,如果内部机制(这只是一个实现细节)包含在测试公共API时应该出现的错误,但实际情况往往是不同的。2看一下给出的例子,你可以采取(至少)两种方法。
第一种是将私有API替换为内部的,并使用InternalsVisibleTo功能来引用包含测试的项目的内部代码片段。
将其添加到要测试的项目(.csproj文件)中

<ItemGroup>
    <InternalsVisibleTo Include="MyProject.Tests" />
</ItemGroup>

字符串
或在给定程序集中的任何文件中使用该属性

[assembly:InternalsVisibleTo("Tests")]


第二种方法是测试外部不可访问的API内部调用的功能。
我也建议看看Coding Journeyman by Julien Fiaffé上的这篇文章

相关问题