【问题标题】:Mock ControllerBase Request using Moq使用 Moq 模拟 ControllerBase 请求
【发布时间】:2020-02-07 10:57:55
【问题描述】:

我在 .Net Core 2.2 中有一个 Web API,如下所示:

[Authorize]
[Route("api/[controller]")]
[ApiController]
public class SomeController : ControllerBase
{
    [HttpPost]
    public async Task<string> SomeMethodPost()
    {
        string returnUrl = $"{this.Request.Scheme}://{this.Request.Host}{this.Request.PathBase}/some/redirect";

        //Some Third Part Service Call

        return serviceResult;
    }
}

我想在单元测试中为我的控制器操作模拟属性“Scheme”、“Host”和“PathBase”。我设法在我的单元测试方法中编写了以下代码:

var request = new Mock<HttpRequest>(MockBehavior.Strict);
request.Setup(x => x.Scheme).Returns("http");
request.Setup(x => x.Host).Returns(HostString.FromUriComponent("http://localhost:8080"));
request.Setup(x => x.PathBase).Returns(PathString.FromUriComponent("/api"));

var mockHttp = new Mock<ControllerBase>(MockBehavior.Strict);
mockHttp.SetupGet(x => x.Request).Returns(request.Object);

但是,最后一行的模拟抛出异常,因为“ControllerBase”的“Request”是不可覆盖的。我理解抽象类的非虚拟属性的限制。有什么解决方法吗?

起订量版本为 4.13.0。

【问题讨论】:

    标签: c# unit-testing .net-core moq xunit.net


    【解决方案1】:

    改变方法。不要模拟被测对象,在本例中是控制器。

    控制器的Request通过HttpContext访问,可以在安排测试时设置。

    例如

    //Arrange
    var request = new Mock<HttpRequest>();
    request.Setup(x => x.Scheme).Returns("http");
    request.Setup(x => x.Host).Returns(HostString.FromUriComponent("http://localhost:8080"));
    request.Setup(x => x.PathBase).Returns(PathString.FromUriComponent("/api"));
    
    var httpContext = Mock.Of<HttpContext>(_ => 
        _.Request == request.Object
    );
    
    //Controller needs a controller context 
    var controllerContext = new ControllerContext() {
        HttpContext = httpContext,
    };
    //assign context to controller
    var controller = new SomeController(){
        ControllerContext = controllerContext,
    };
    
    String expected = "expected value here";
    
    //Act
    String actual = await controller.SomeMethodPost();
    
    
    //Assert
    Assert.AreEqual(expected, actual);
    
    //...
    

    【讨论】:

    • 这很棒。我在寻找什么。
    猜你喜欢
    • 2021-04-01
    • 2011-06-13
    • 2019-09-11
    • 2010-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多