Web API - 使用moq进行集成测试的Owin中的HttpContext.Current问题

问题描述 投票:2回答:2

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

问题在于我的服务架构,在存储库层,我正在利用HttpContext.Current从头部(比如UserId)中检索值。 See this answer

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

我通过这个伟大的answer关于将IOwinContext纳入存储库。我已经尝试过它并且它可以用于自托管,但我的最终目标是在IIS上部署应用程序。

我的问题:

  • 我的代码有没有办法处理IIS上的集成测试和实际服务部署的OWIN自托管用例?
  • 我的架构有什么问题吗?像我这样的东西根本不应该使用OWIN,并使用其他工具如POSTMAN进行测试。

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

编辑:

正如@Nkosi所建议的那样,为了与owin进行集成测试,我可能需要模拟我的HeaderService。我不知道如何使用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()返回模拟响应。截至目前我不知道如何将我的模拟服务注入实际的控制器方法调用。

有什么建议?

c# asp.net-web-api owin moq httpcontext
2个回答
1
投票

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

这是代码:

var container = new UnityContainer();

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

0
投票

我按照这个主题在我的旧项目中使用HttpContextBase

Moq: unit testing a method relying on HttpContext

HttpContextWrapper是HttpContext类的包装器,可以像这样构造一个HttpContextWrapper:

var wrapper = new HttpContextWrapper(HttpContext.Current);

您可以使用Moq模拟HttpContextBase并设置它的期望

var mockContext = new Mock<HttpContextBase>();
© www.soinside.com 2019 - 2024. All rights reserved.