Web API- httpContext.Current在OWIN中进行的问题,用于使用MOQ集成测试



我正在构建将在IIS环境中托管的Web API应用程序。为了执行我的服务的终点到端集成测试(没有嘲笑),我正在使用Owin。

我的服务体系结构,在我使用HttpContext.Current的存储库层中的问题深处是从标题(例如用户ID)检索值。看到此答案

如果您查看了上述代码,我将在整个应用程序中使用GetUserInfo方法来获取当前的用户信息。另一种方法是将其作为所有方法中的参数传递(我个人不想这样做)。

我经历了这个很好的答案,内容涉及将IOwinContext包括在存储库中。我已经尝试过它,它用于自我托管,但我的最终目标是在IIS上部署应用程序。

我的问题:

  • 我的代码可以采用任何方式处理Owin自托管的用例以进行集成测试&IIS上的实际服务部署?
  • 我的架构有任何问题吗?类似我根本不应该使用Owin,并使用其他工具(例如POSTMAN)进行测试。

如果需要,我可以发布一些代码。

编辑:

正如@nkosi所建议的,我可能必须模拟我的HeaderService才能与Owin进行集成测试。我不确定如何使用moq模拟一种某种方法。这是我的代码。它的剥离版本以使尽可能简单。

代码:

public class CreditController : ApiController
{
    private readonly ICreditService _creditService;
    public CreditController(ICreditService creditService)
    {
        _creditService = creditService;
    }
    public IHttpActionResult CreditSummary([FromUri]string requestId)
    {
        var response = _creditService.GetCreditSummary(requestId);
        return Ok(response);
    }
}
public class CreditService : ICreditService
{
    private readonly IHeaderService _headerService;
    private readonly ICreditRepository _creditRepository;
    public CreditService(ICreditRepository creditRepository, IHeaderService headerService)
    {
        _headerService = headerService;
        _creditRepository = creditRepository;
    }
    public CreditObj GetCreditSummary(string req)
    {
        var userId = _headerService.GetHeaderFromHttpRequest();//Get User
        var response = _creditRepository.GetDataFromDatabase(req, userId);
        return response;
    }
}
public interface IHeaderService
{
    string GetHeaderFromHttpRequest();
}
public class HeaderService : IHeaderService
{
    public string GetHeaderFromHttpRequest()
    {
        return HttpContext.Current.Request.Headers["USERID"];
    }
}

以下是我进行集成测试的代码:我将OWIN用于自助宿主。因此,我想调用控制器方法,但我的GetHeaderFromHttpRequest方法应返回模拟响应。

[TestClass]
public class IntegrationTest
{
    private static HttpClient _client;
    private static IDisposable _webApp;
    [ClassInitialize]
    public static void Init(TestContext testContext)
    {
        _webApp = WebApp.Start<Startup>(url: Url);
        _client = new HttpClient
        {
            BaseAddress = new Uri(Url)
        };
    }
    [TestMethod]
    public void TestDashboard()
    {
        var headerStub = new Mock<IHeaderService>();
        headerStub.Setup(s => s.GetHeaderFromHttpRequest())
            .Returns("MockUserId");
        var builder = new UriBuilder(Url + "api/Credit/CreditSummary");
        HttpResponseMessage responseMessage = _client.GetAsync(builder.ToString()).Result;
        Assert.IsNotNull(responseMessage);
    }
}
public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();
        WebApiConfig.Register(config); //This method having all routing/dependancy configuration
        app.UseWebApi(config);
    }
}

问题:

  • 当我调试此测试案例时,如何确保_headerService.GetHeaderFromHttpRequest()返回模拟响应。截至目前,我不知道如何将模拟服务注入实际控制器方法调用。

任何建议?

基于 @nkosi的建议,我能够模拟HeaderService进行集成测试。

这是代码:

var container = new UnityContainer();
var mock = new Mock<IHeaderService>();
mock.Setup(x => x.GetHeaderFromHttpRequest()).Returns("MockId");
container.RegisterInstance(mock.Object);

我遵循此主题并在我的旧项目中使用HttpContextBase

ioq:单元测试一种依赖httpcontext

的方法

HttpContextWrapper是httpcontext类的包装器,可以构造这样的httpcontextwrapper:

var wrapper = new HttpContextWrapper(HttpContext.Current);

您可以模拟HttpContextBase并使用MOQ

设置您的期望
var mockContext = new Mock<HttpContextBase>();

最新更新