jeudi 9 avril 2015

MVC4 / Mocking Controller.Request

I´m currently working on a MVC4 Project. As I did a few refactorings the tests should be changed too.


In the first scenario a session hash had to be passed included within the URL. That being nasted, I decided to pass it to the server as a Request header.


Example:



[HttpPost]
public ActionResult Generate(ClipGenerateRequest request)
{
string hash = Request.Headers["hash"];

ClipGenerationResponse responseModel = new ClipGenerationResponse();

return Json(responseModel, JsonRequestBehavior.AllowGet);
}


The problem now seems to be that I'm unable to mock the Request object to a custom one as the Request object is a read-only object. Dynamically setting the header doesn't work, as the Request is null when performing Unit Tests. So the following won't work:



[TestMethod]
public void GenerateTest()
{
GenerationController target = new GenerationController(this.loginModelMock, this.clipTemplateModelMock, this.clipTemplateFieldModelMock);
target.Request = this.requestBase;
string templateId = "0";

ActionResult actual = target.Generate(templateId);
Assert.AreEqual(typeof(JsonResult), actual.GetType());
Assert.AreEqual(typeof(ClipGenerationResponse), ((JsonResult)actual).Data.GetType());
}


Where this.requestBase would be mock created with Moq.



public HttpContextBase CreateMockHttpContext()
{
var serverVariables = new NameValueCollection {
{ "UserHostAddress", "127.0.0.1" },
{ "UserAgent", "Unit Test Value" }
};

var httpRequest = new Moq.Mock<HttpRequestBase>();
httpRequest.SetupGet(x => x.Headers).Returns(
new System.Net.WebHeaderCollection {
{"hash", "somehash"}
}
);

httpRequest.Setup(x => x.ServerVariables.Get(It.IsAny<string>()))
.Returns<string>(x =>
{
return serverVariables[x];
});

var httpContext = (new Moq.Mock<HttpContextBase>());
httpContext.Setup(x => x.Request).Returns(httpRequest.Object);

return httpContext.Object;
}


Nor the static way would work:



target.Request.Headers["hash"] = "hash";


So, I'm wondering how this could be fixed nicely. I could always obtain the Request in the Constructor, set a class variable to hold the Request, and then mock the getter / setter for testing purposes, but I'd rather use a nicer way to do it. Though I don't seem to know a way to get it working.


Any advice is welcome.


Kind Regards, Lars


PS: Please note that some class names may have been altered for preview.


Aucun commentaire:

Enregistrer un commentaire