【问题标题】:How to mock HttpContext in ASP.NET Core [duplicate]如何在 ASP.NET Core 中模拟 HttpContext [重复]
【发布时间】:2021-04-15 15:04:47
【问题描述】:

我正在尝试模拟 HttpContext 来测试我的 UsersController。 UsersController 继承自

public abstract class ControllerBase

而 HttpContext 是 ControllerBase 的一个属性

public HttpContext HttpContext { get; }

这是我要测试的UsersContoller中的方法

 public async Task<IActionResult> Register([FromBody] UserViewModel model)
        {
            _logger.LogDebug("Register new user");

            var user = mapper.Map<User>(model);
            user.Company.Active = false;

            var result = await userManager.CreateAsync(user, model.Password);

            if (result.Succeeded)
            {
                await userManager.AddToRoleAsync(user, Roles.NO_ACCESS);

                //send confirmation email

                string confirmationToken = userManager.GenerateEmailConfirmationTokenAsync(user).Result;

                HostString hostString = HttpContext.Request.Host; //I need to mock httpcontext for this 

                this.mailSender.SendConfirmationMailAsync(user, hostString, confirmationToken);

                return Ok();
            }
            else
            {
                _logger.LogInformation("User could not be registered Errors:");
                result.Errors.ToList().ForEach(e => _logger.LogInformation(e.Description));

                return BadRequest(result.Errors);
            }

        }

这是我的 BaseTestContoller,其中初始化了测试设置

[SetUp]
        public void Setup()
        {
            var dbContext = CreateDbContext();

            CreateUserManager();
            CreateMailSender(dbContext);
            CreateMockImapper();
            CreateMockIlogger();
            
            usersController = new Mock<UsersController>(
               userManagerMock.Object,
               new CompanyService(dbContext),
               mailSenderMock,
               new Mock<IConfiguration>().Object,
               iMapperMock.Object,
               iLoggerFactoryMock.Object);

        }

我尝试了很多选择,但都没有成功,如果有人可以帮助我,那就太好了。 提前致谢

更新

usersController = new Mock<UsersController>(
               userManagerMock.Object,
               new CompanyService(dbContext),
               mailSenderMock,
               new Mock<IConfiguration>().Object,
               iMapperMock.Object,
               iLoggerFactoryMock.Object);

            var conterllerContext = new ControllerContext() { HttpContext = new DefaultHttpContext() { } };                             
            HostString host = new HostString("test.de");

            conterllerContext.HttpContext.Request.Host = host;

            usersController.Setup(c => c.HttpContext).Returns(conterllerContext.HttpContext);

现在我遇到了设置问题。 userController.setup 返回此消息: System.NotSupportedException:不支持的表达式:c => c.HttpContext 不可覆盖的成员(此处:ControllerBase.get_HttpContext)不得用于设置/验证表达式。

【问题讨论】:

  • 这是一个例子,我已经尝试过了,但不起作用HttpContext context = new DefaultHttpContext(); HostString host = new HostString("test.de"); context.Request.Host = host;usersController.Setup(c =&gt; c.HttpContext).Returns(context);
  • 就我个人而言,我不会模拟 HttpContext,而是使用一种方法创建一个接口,该方法为您提供主机并进行两个实现:一个模拟实现和一个使用 HttpContext 提供真实主机的实现。您可以在测试中使用模拟并在生产中使用真实的。
  • @lordvlad30 问题是“Controllbase”是“Microsoft.AspNetCore.Mvc”的一部分。我无法更改它。因此我需要嘲笑它。但下次我会按照你的方式做。谢谢

标签: asp.net-mvc asp.net-core testing


【解决方案1】:

您可以使用ControllerContext 将上下文设置为DefaultHttpContext,您可以根据需要进行修改。

var ctx = new ControllerContext() { HttpContext = new DefaultHttpContext()};
var tested = new MyCtrl();
tested.ControllerContext = ctx;

【讨论】:

  • 首先,感谢您的回答。你知道我如何设置我的模拟 userController 来返回这个 Httpcontxt 吗?
【解决方案2】:

你不能做一个模拟服务来获取主机地址吗(我对模拟库不是很熟悉)。

类似这样的:

class IHostService {
 string GetHost();
}

public class HostService {
  // create constructor with httpcontextaccessor    
 public string GetHost() {
  return _httpContextAccessor.HttpContext.Request.Host;
 }
}
public class MockHostService {
  public string GetHost() {
    return "test.de";
  }
}

在您的模拟课程中,您可能可以像添加mailSenderMock 一样添加此服务。在你的控制器中你使用string host = _hostService.GetHost()。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2010-11-29
  • 2019-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多