尝试为 ASP.Net Core 3.1 单元测试创​​建 Mock.Of<ControllerContext>() 时出错

Sha*_*Wet 4 c# unit-testing moq asp.net-core

根据此处定义的 Moq 快速入门的最后一部分,我尝试配置以下模拟,以便将表单值传递给测试中的控制器方法:

var formCollection = new FormCollection(
                new System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues>()
            {
                    {"mAction", "someAction" },
                    {"mRefId", "0" }
            });

        var controllerContext = Mock.Of<ControllerContext>(ctx =>
            ctx.HttpContext.Request.Form == formCollection);
        
        controller.ControllerContext = controllerContext;
Run Code Online (Sandbox Code Playgroud)

但是,当运行测试时,它失败Mock.Of<>并出现以下错误:

System.NotSupportedException:不支持的表达式:mock => mock.HttpContext

不可重写的成员(此处:ActionContext.get_HttpContext)不得在设置/验证表达式中使用。

我缺少什么?我是否按照快速入门文档中定义的示例执行相同的操作?

Nko*_*osi 6

该错误是因为ControllerContext.HttpContextproperty 不是virtual,因此 Moq 无法覆盖它。

考虑使用实际的ControllerContext和模拟的 aHttpContext来分配给属性

var formCollection = new FormCollection(new Dictionary<string, StringValues>()
    {
        {"mAction", "someAction" },
        {"mRefId", "0" }
    });

var controllerContext = new ControllerContext() {
    HttpContext = Mock.Of<HttpContext>(ctx => ctx.Request.Form == formCollection)
};

controller.ControllerContext = controllerContext;

//...
Run Code Online (Sandbox Code Playgroud)

或者甚至使用DefaultHttpContext并分配所需的值

var formCollection = new FormCollection(new Dictionary<string, StringValues>()
    {
        {"mAction", "someAction" },
        {"mRefId", "0" }
    });

HttpContext httpContext = new DefaultHttpContext();
httpContext.Request.Form = formCollection;

var controllerContext = new ControllerContext() {
    HttpContext = httpContext
};

controller.ControllerContext = controllerContext;

//...
Run Code Online (Sandbox Code Playgroud)