Я создаю приложение Web API, которое будет размещено в среде IIS. Для выполнения комплексного тестирования моего сервиса (без насмешек) я использую OWIN.
Проблема глубоко в моей сервисной архитектуре, на уровне хранилища я использую HttpContext.Current
для получения значений из заголовка (скажем, UserId). Смотрите этот ответ
Если вы посмотрите на приведенный выше код, я использую метод GetUserInfo
во всем приложении для получения информации о текущем пользователе. Другой способ сделать это - передать его как параметр во всех методах (что я лично не хочу делать).
Я прошел этот замечательный ответ о включении IOwinContext
в хранилище. Я попробовал это, и это работало для самостоятельного размещения, но моя конечная цель - развернуть приложение на IIS.
Мои вопросы:
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()
возвращает ложный ответ. На данный момент я не знаю, как я могу внедрить мою службу пересмешки в фактический вызов метода контроллера.Любой совет?
Основываясь на предложении @Nkosi, я смог издеваться над HeaderService
для моего интеграционного тестирования.
Вот код:
var container = new UnityContainer();
var mock = new Mock<IHeaderService>();
mock.Setup(x => x.GetHeaderFromHttpRequest()).Returns("MockId");
container.RegisterInstance(mock.Object);
Я следовал этой теме и использую HttpContextBase
в моем старом проекте.
Moq: модульное тестирование метода, основанного на HttpContext
HttpContextWrapper
является оберткой для класса HttpContext, может создать HttpContextWrapper следующим образом:
var wrapper = new HttpContextWrapper(HttpContext.Current);
Вы можете HttpContextBase
и настроить свои ожидания на нем, используя Moq
var mockContext = new Mock<HttpContextBase>();
HttpContext.Current
работал ), тогда вам все равно нужно будетHttpContext.Current
абстрактную службу, чтобы избежать этой статической связи.HttpContext.Current
и / илиHeaderService
(сервис, который использует объект HttpContext) в моем интеграционном тесте? Не уверен, что это хороший способ что-то подделать при проведении интеграционного тестирования.