I have a Web API in .Net Core 2.2 as below:
[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;
}
}
I want to mock the properties "Scheme", "Host" and "PathBase" for my controller action in my unit test. I managed to write below code in my unit test method:
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);
However, the mock in last line throws exception as "Request
" of "ControllerBase
" is non overridable. I understand the limitation with non virtual properties of abstract classes. Is there any workaround for this?
Moq version is 4.13.0.
Change approach. Do not mock the subject under test, which in this case is the controller.
The controller's Request
is accessed via the HttpContext
which can be set when arranging the test.
For example
//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);
//...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With