Eu tenho um controlador em c # usando a estrutura do asp.net MVC
public class HomeController:Controller{
public ActionResult Index()
{
if (Request.IsAjaxRequest())
{
//do some ajaxy stuff
}
return View("Index");
}
}
Eu recebi algumas dicas sobre zombaria e esperava testar o código com o seguinte e 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);
No entanto, continuo recebendo este erro:
Exceção System.ArgumentNullException: System.ArgumentNullException: O valor não pode ser nulo. Nome do parâmetro: request em System.Web.Mvc.AjaxRequestExtensions.IsAjaxRequest (solicitação HttpRequestBase)
Como o Request
objeto no controlador não possui setter. Tentei fazer esse teste funcionar corretamente usando o código recomendado de uma resposta abaixo.
Isso usava o Moq em vez do RhinoMocks e, ao usar o Moq, uso o seguinte para o mesmo teste:
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);
mas obtenha o seguinte erro:
Exceção System.ArgumentException: System.ArgumentException: instalação inválida em um membro não substituível: x => x.Headers ["X-Requested-With"] em Moq.Mock.ThrowIfCantOverride (instalação da expressão, MethodInfo methodInfo)
Mais uma vez, parece que não consigo definir o cabeçalho da solicitação. Como faço para definir esse valor no RhinoMocks ou no Moq?
Respostas:
Usando Moq :
ATUALIZADA:
Zombe
Request.Headers["X-Requested-With"]
ou emRequest["X-Requested-With"]
vez deRequest.IsAjaxRequest()
.fonte
Para quem usa o NSubstitute, eu consegui modificar as respostas acima e fazer algo assim ... (onde Detalhes é o nome do método Action no controlador)
fonte
Aqui está uma solução funcional usando o RhinoMocks. Baseei-o em uma solução Moq que encontrei em http://thegrayzone.co.uk/blog/2010/03/mocking-request-isajaxrequest/
fonte
Is AjaxRequest é um método de extensão. Então você pode fazer isso da seguinte maneira usando o Rhino:
fonte
Parece que você está procurando por isso,
Uso no Controlador:
fonte
Você precisa zombar do HttpContextBase e colocá-lo em sua propriedade ControllerContext, assim:
fonte
Para fazer
IsAjaxRequest()
retornar falso durante o teste de unidade, você precisa configurar os Cabeçalhos de solicitação e o valor da coleção de solicitação no método de teste, conforme indicado abaixo:O motivo da configuração de ambos está oculto na implementação de IsAjaxRequest (), que é fornecida abaixo:
Ele usa a coleção de solicitações e o cabeçalho; é por isso que precisamos criar a configuração para a coleção de cabeçalhos e solicitações.
isso fará com que a solicitação retorne false quando não for uma solicitação ajax. para torná-lo verdadeiro, você pode fazer o seguinte:
fonte
Encontrei outra maneira de adicionar um objeto HttpRequestMessage à sua solicitação durante a API da Web, conforme a seguir
fonte
(Um pouco tarde para a festa, mas eu segui uma rota diferente, então pensei em compartilhar)
Para ir para uma maneira pura de código / zombaria de testar isso sem criar zombarias para as classes Http, implementei um IControllerHelper que possui um método Initialise que usa a Solicitação como parâmetro e depois expõe as propriedades que desejo, por exemplo:
Então, no meu controlador, eu chamo initialize no início do método:
E então meu código depende apenas de dependências simuláveis.
Para testes funcionais, substituo o iControllerHelper na composição por um substituto.
fonte