C# dotnet核心控制器中的非公共单元测试方法

C# dotnet核心控制器中的非公共单元测试方法,c#,unit-testing,asp.net-core,C#,Unit Testing,Asp.net Core,假设在一个MVC5控制器中,我的控制器中有一个被控制器中的其他方法调用的方法,但我不希望它对用户可用。如果我想模仿它,它会是这样的: [ChildActionOnly] public virtual string DoSpecialFormatting(string mySpecialString) { // stuff } 或者我可以将[assembly:InternalsVisibleTo(“MyLittleProject.Tests”)]和[assembly:InternalsV

假设在一个MVC5控制器中,我的控制器中有一个被控制器中的其他方法调用的方法,但我不希望它对用户可用。如果我想模仿它,它会是这样的:

[ChildActionOnly]
public virtual string DoSpecialFormatting(string mySpecialString)
{
    // stuff
}
或者我可以将
[assembly:InternalsVisibleTo(“MyLittleProject.Tests”)]
[assembly:InternalsVisibleTo(“DynamicProxy Assembly2”)]
(用于Moq)扔进
AssemblyInfo.cs
,并将该方法标记为
internal
,而不是
public

internal virtual string DoSpecialFormatting(string mySpecialString)
{
    // stuff
}

现在没有
ChildActionOnly
,我在新的ASP.NET核心项目中也没有看到
AssemblyInfo.cs
文件,我的控制器类中怎么会有web用户无法访问但仍然可以模拟的方法呢?

您可以将该方法提取到一个类中,即名为SpecialFormatter,并通过DI注入控制器。要测试控制器,可以模拟该类

class SpecialFormatter
{ 
   public string DoSpecialFormatting(string mySpecialString)
   {
       // stuff
   }
}
然后在你的控制器里

class SomeController : Controller
{

   private SpecialFormatter _formatter;

   public SomeController(SpecialFormatter formatter)
   {
      _formatter = formatter;
   }

   public ActionResult SomeAction(string input)
   {
      string output = _formatter.DoSpecialFormatting(input);
      // stuff
   }

}

您可以将该方法提取到一个类,即名为SpecialFormatter的类,并通过DI注入控制器。要测试控制器,可以模拟该类

class SpecialFormatter
{ 
   public string DoSpecialFormatting(string mySpecialString)
   {
       // stuff
   }
}
然后在你的控制器里

class SomeController : Controller
{

   private SpecialFormatter _formatter;

   public SomeController(SpecialFormatter formatter)
   {
      _formatter = formatter;
   }

   public ActionResult SomeAction(string input)
   {
      string output = _formatter.DoSpecialFormatting(input);
      // stuff
   }

}

在ASP.NET内核中,该属性称为
NonActionAttribute

[NonAction]
public virtual string DoSpecialFormatting(string mySpecialString)
{
    // stuff
}

它比内部的要好。

在ASP.NET核心中,该属性被称为
NonActionAttribute

[NonAction]
public virtual string DoSpecialFormatting(string mySpecialString)
{
    // stuff
}

Imho比internal好。

如果这样做,应该为提取的类提供一个接口,并将其传递给类的构造函数。通过这种方式,只要类共享公共接口,就可以将模拟类注入到该类中。正如您现在所拥有的,您只能在中注入具体的实现,而不能正确地模拟它。如果您这样做,您应该为提取的类提供一个接口,并将其传递给类的构造函数。通过这种方式,只要类共享公共接口,就可以将模拟类注入到该类中。正如您现在所拥有的,您只能将具体的实现注入其中,而无法正确模拟它。您可以做的一种方法是,将所有内部逻辑放在一个共享框架项目中,然后将InternalsVisibleTo用于您的测试项目。您可以做的一种方法是,将您所有的内部逻辑放在一个共享框架项目中,然后使用InternalsVisibleTo进行测试项目。谢谢,这正是我想要的。我希望能够做到这一点,而不必提取到另一个类,特别是对于大量使用服务器状态的方法。谢谢,这正是我想要的。我希望能够做到这一点,而不必提取到另一个类,特别是对于大量使用服务器状态的方法。