Asp.net mvc 跳过方法执行到单元测试控制器流

Asp.net mvc 跳过方法执行到单元测试控制器流,asp.net-mvc,unit-testing,dependency-injection,nunit,moq,Asp.net Mvc,Unit Testing,Dependency Injection,Nunit,Moq,} 我正在尝试对我的控制器进行单元测试。ConcreteClass构造函数及其方法ConcreteClassMethod都对HttpRequest变量有一些依赖性,我无法从单元测试中传递这些变量 我想要一种方法,在调用DemoController的默认操作时,可以跳过ConcreteClass的构造函数和ConcreteClassMethod的执行。您不能创建对象的新实例并阻止调用构造函数。您必须创建一个空的无参数构造函数 public class DemoController : Contro

}

我正在尝试对我的控制器进行单元测试。ConcreteClass构造函数及其方法ConcreteClassMethod都对HttpRequest变量有一些依赖性,我无法从单元测试中传递这些变量


我想要一种方法,在调用DemoController的默认操作时,可以跳过ConcreteClass的构造函数和ConcreteClassMethod的执行。

您不能创建对象的新实例并阻止调用构造函数。您必须创建一个空的无参数构造函数

public class DemoController : Controller
{


    private readonly ICommonOperationsRepository _commonRepo;

    public DemoController (ICommonOperationsRepository commonRepo)
    {
       _commonRepo = commonRepo;
    }
    public ActionResult Default()
    {
       var model = new DemoModel();
       try
       {
           **ConcreteClass cc = new ConcreteClass(Request.ServerVariables["HTTP_X_REWRITE_URL"].ToString());
            cc.ConcreteClassMethod();**

           model.ListTopListing.AddRange(_commonRepo.GetListings());
        }
        catch (Exception ex)
        {
            ExceptionHandler objErr = new ExceptionHandler(ex, "DemoController .Default()\n Exception : " + ex.Message);
            objErr.LogException();
         }
         return View(model);
     }
或者重新考虑方法的工作方式,使其不依赖于在构造函数中传递字符串:

public class ConcreteClass
{
    private string MyString;

    // Your constructor
    public ConcreteClass(string myString)
    {
        this.MyString = myString;
    }

    // Parameterless constructor
    public ConcreteClass()
    {
        // Do nothing, no code
    }

    // A method that might use MyString
    public void DoSomethingWithMyString()
    {
        var trimmedString = this.MyString.Trim();
    }
}
但是,这可能无法解决问题,请记住,您想要注入
请求
变量,并且您没有访问它们的权限,您不能只执行以下操作:

public class ConcreteClass
{        
    // No constructor required anymore

    // Pass the string in to the methods that need the string
    public void DoSomethingWithMyString(string myString)
    {
        var trimmedString = myString.Trim();
    }

    // Pass the string in to the methods that need the string
    public void DoSomethingElseWithMyString(string myString)
    {
        var trimmedString = Int32.Parse(myString);
    }
}
现在,在单元测试中,您可以使用第二个构造函数并将值传入:

public class DemoController : Controller
{
    private string HttpRewriteUrl;

    public DemoController()
    {
        this.HttpRewriteUrl = Request.ServerVariables["HTTP_X_REWRITE_URL"].ToString();
    }

    // Custom constructor for unit testing
    public DemoController(string httpRewriteUrl)
    {
        this.HttpRewriteUrl = httpRewriteUrl;
    }

    public ActionResult Default()
    {
        // Get the value from the object
        ConcreteClass cc = new ConcreteClass(this.HttpRewriteUrl);
        cc.ConcreteClassMethod();
    }
}

无法创建对象的新实例并阻止调用构造函数。您必须创建一个空的无参数构造函数。要么这样,要么重新考虑方法的工作方式。您还可以使用依赖项注入在中注入值。不确定如何执行此操作。你能详细解释一下吗?请看我的答案,特别是我刚才补充的最后一点。如果您需要更多信息,请告诉我。请参阅修正案。问题是cc.ConcreteClassMethod()也会访问一些我希望避免的请求变量。我建议以相同的方式将它们作为控制器的参数传入。您会发现,如果您传入相应的值,它会使您更清楚地了解这些方法的作用。
var controller = new DemoController("your value to pass in here");
controller.Default();