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

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

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

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

Любой совет?

Ответы [ 2 ]

1 голос
/ 24 марта 2019

По предложению @Nkosi я смогла высмеять HeaderService для моего интеграционного тестирования.

Вот код:

var container = new UnityContainer();

var mock = new Mock<IHeaderService>();
mock.Setup(x => x.GetHeaderFromHttpRequest()).Returns("MockId");
container.RegisterInstance(mock.Object);
0 голосов
/ 23 марта 2019

Я следовал этой теме и использую HttpContextBase в моем старом проекте.

Moq: модульное тестирование метода, основанного на HttpContext

HttpContextWrapper - это оболочкадля класса HttpContext, можно создать HttpContextWrapper следующим образом:

var wrapper = new HttpContextWrapper(HttpContext.Current);

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

var mockContext = new Mock<HttpContextBase>();
...