Web API - проблемы с HttpContext.Current в owin для тестирования интеграции с использованием moq

2

Я создаю приложение Web API, которое будет размещено в среде IIS. Для выполнения комплексного тестирования моего сервиса (без насмешек) я использую OWIN.

Проблема глубоко в моей сервисной архитектуре, на уровне хранилища я использую HttpContext.Current для получения значений из заголовка (скажем, UserId). Смотрите этот ответ

Если вы посмотрите на приведенный выше код, я использую метод GetUserInfo во всем приложении для получения информации о текущем пользователе. Другой способ сделать это - передать его как параметр во всех методах (что я лично не хочу делать).

Я прошел этот замечательный ответ о включении IOwinContext в хранилище. Я попробовал это, и это работало для самостоятельного размещения, но моя конечная цель - развернуть приложение на IIS.

Мои вопросы:

  • Есть ли способ, которым мой код может обрабатывать как сценарии использования собственного хостинга OWIN для тестирования интеграции, так и фактического развертывания службы в IIS?
  • Есть ли проблемы с моей архитектурой? Что-то вроде того, что я вообще не должен использовать OWIN, а для тестирования использую другие инструменты, такие как POSTMAN.

Я могу опубликовать код, если это требуется.

Редактировать:

В соответствии с предложением @Nkosi мне, возможно, придется HeaderService мой 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() возвращает ложный ответ. На данный момент я не знаю, как я могу внедрить мою службу пересмешки в фактический вызов метода контроллера.

Любой совет?

  • 0
    Вы все еще можете сделать тестирование с помощью макета. Если в этом случае вы на самом деле не работаете на IIS ( это то, что вам нужно для того, чтобы HttpContext.Current работал ), тогда вам все равно нужно будет HttpContext.Current абстрактную службу, чтобы избежать этой статической связи.
  • 0
    Я не уверен, правильно ли я вас понял. Вы говорите, что я должен издеваться над HttpContext.Current и / или HeaderService (сервис, который использует объект HttpContext) в моем интеграционном тесте? Не уверен, что это хороший способ что-то подделать при проведении интеграционного тестирования.
Показать ещё 1 комментарий
Теги:
asp.net-web-api
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: модульное тестирование метода, основанного на HttpContext

HttpContextWrapper является оберткой для класса HttpContext, может создать HttpContextWrapper следующим образом:

var wrapper = new HttpContextWrapper(HttpContext.Current);

Вы можете HttpContextBase и настроить свои ожидания на нем, используя Moq

var mockContext = new Mock<HttpContextBase>();

Ещё вопросы

Сообщество Overcoder
Наверх
Меню