У меня есть контроллер в C # с использованием ASP.Net MVC Framework
public class HomeController:Controller{
public ActionResult Index()
{
if (Request.IsAjaxRequest())
{
//do some ajaxy stuff
}
return View("Index");
}
}
Я получил несколько советов по насмешкам и надеялся протестировать код с помощью следующего и RhinoMocks
var mocks = new MockRepository();
var mockedhttpContext = mocks.DynamicMock<HttpContextBase>();
var mockedHttpRequest = mocks.DynamicMock<HttpRequestBase>();
SetupResult.For(mockedhttpContext.Request).Return(mockedHttpRequest);
var controller = new HomeController();
controller.ControllerContext = new ControllerContext(mockedhttpContext, new RouteData(), controller);
var result = controller.Index() as ViewResult;
Assert.AreEqual("About", result.ViewName);
Однако я продолжаю получать эту ошибку:
Исключение System.ArgumentNullException: System.ArgumentNullException: значение не может быть нулевым. Имя параметра: запрос в System.Web.Mvc.AjaxRequestExtensions.IsAjaxRequest (запрос HttpRequestBase)
Поскольку Request
объект на контроллере не имеет установщика. Я попытался заставить этот тест работать правильно, используя рекомендованный код из ответа ниже.
Это использовало Moq вместо RhinoMocks, и при использовании Moq я использую следующее для того же теста:
var request = new Mock<HttpRequestBase>();
// Not working - IsAjaxRequest() is static extension method and cannot be mocked
// request.Setup(x => x.IsAjaxRequest()).Returns(true /* or false */);
// use this
request.SetupGet(x => x.Headers["X-Requested-With"]).Returns("XMLHttpRequest");
var context = new Mock<HttpContextBase>();
context.SetupGet(x => x.Request).Returns(request.Object);
var controller = new HomeController(Repository, LoginInfoProvider);
controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller);
var result = controller.Index() as ViewResult;
Assert.AreEqual("About", result.ViewName);
но получите следующую ошибку:
Исключение System.ArgumentException: System.ArgumentException: недопустимая установка для не перезаписываемого члена: x => x.Headers ["X-Requested-With"] в Moq.Mock.ThrowIfCantOverride (настройка выражения, MethodInfo methodInfo)
Опять же, похоже, что я не могу установить заголовок запроса. Как мне установить это значение, в RhinoMocks или Moq?
Ответы:
С помощью Moq :
ОБНОВЛЕНО:
Макет
Request.Headers["X-Requested-With"]
илиRequest["X-Requested-With"]
вместоRequest.IsAjaxRequest()
.источник
Для любого, кто использует NSubstitute, я смог изменить приведенные выше ответы и сделать что-то вроде этого ... (где Details - это имя метода Action на контроллере)
источник
Вот рабочее решение с использованием RhinoMocks. Я основал его на решении Moq, которое нашел по адресу http://thegrayzone.co.uk/blog/2010/03/mocking-request-isajaxrequest/
источник
Является ли AjaxRequest методом расширения. Таким образом, вы можете сделать это следующим образом, используя Rhino:
источник
Похоже, вы ищете это,
Использование в контроллере:
источник
Вам нужно смоделировать HttpContextBase и поместить его в свойство ControllerContext, например:
источник
Чтобы
IsAjaxRequest()
вернуть false во время модульного теста, вам нужно настроить заголовки запросов, а также значение сбора запросов в вашем методе тестирования, как указано ниже:Причина установки обоих скрыта в реализации IsAjaxRequest (), которая приведена ниже:
Он использует как коллекцию запросов, так и заголовок, поэтому нам нужно создать настройки как для заголовка, так и для коллекции запросов.
это сделает запрос на возврат false, когда это не ajax-запрос. чтобы вернуть значение true, вы можете сделать следующее:
источник
Я нашел другой способ добавить объект HttpRequestMessage в ваш запрос во время Web API следующим образом
источник
(Немного опоздал на вечеринку, но я пошел по другому маршруту, поэтому думал, что поделюсь)
Чтобы перейти к чистому коду / способу проверки с целью проверки этого без создания макетов для классов Http, я реализовал IControllerHelper, который имеет метод Initialise, который принимает запрос в качестве параметра, а затем предоставляет свойства, которые я хочу, например:
Затем в моем контроллере я вызываю инициализацию в начале метода:
И тогда мой код зависит только от поддельных зависимостей.
Для функциональных тестов я просто перезаписываю iControllerHelper в составе заменителя.
источник