1

In my Asp.net core 1 app I have controller with following method:

[Microsoft.AspNetCore.Mvc.HttpPost()]
[Microsoft.AspNetCore.Mvc.RequireHttps]
public async System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.IActionResult> Save()
{
    if (ModelState.IsValid)
    {
        try
        {
            var pass = Request.Form["password"].ToString();
            var pass1 = Request.Form["password1"].ToString();
            if (!pass.Equals(pass1))
            {
                return View("~/Views/PasswordRecovery.cshtml");
            }                  
        }
        catch (System.Exception ex)
        {
            return View("~/Views/Message.cshtml");
        }
    }
    return View("~/Views/Message.cshtml");
}

I want to write a test for this method. So I have written this:

[Xunit.Fact]
public async System.Threading.Tasks.Task SavePassNotEqualTest()
{
    var controller = new Controllers.PasswordRecoveryController(_mockRepo.Object);
    var dic = new System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues>();
    dic.Add("password", "test");
    dic.Add("password1", "test1");
    var collection = new Microsoft.AspNetCore.Http.FormCollection(dic);
    controller.Request.Form = collection;  //request is null

    var result = await controller.Save();
    var viewResult = Xunit.Assert.IsType<Microsoft.AspNetCore.Mvc.ViewResult>(result);
    Xunit.Assert.Equal("~/Views/Message.cshtml", viewResult.ViewName);
}

The problem is that I need to set some test values to Form, Form is in Request, and Request is NULL. I can not find, how can I create some not NULL request and fill it's Form with values.

EDIT Answers helped me to finish up with following solution:

I've created a method that will return a FormCollection:

private Microsoft.AspNetCore.Http.FormCollection GetFormCollection()
{
    var dic = new System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues>();
    dic.Add("password", "test");
    dic.Add("password1", "test1");
    return new Microsoft.AspNetCore.Http.FormCollection(dic);
}

And my test method is:

[Xunit.Fact]
public async System.Threading.Tasks.Task SavePassNotEqualTest()
{           
    var controller = new Findufix.Controllers.PasswordRecoveryController(_mockRepo.Object);

    var httpContext = new Moq.Mock<Microsoft.AspNetCore.Http.HttpContext>();
    httpContext.Setup( x => x.Request.Form).Returns(GetFormCollection());  

    controller.ControllerContext.HttpContext = httpContext.Object;          

    var result = await controller.Save();
    var viewResult = Xunit.Assert.IsType<Microsoft.AspNetCore.Mvc.ViewResult>(result);
    Xunit.Assert.Equal("~/Views/PasswordRecovery.cshtml", viewResult.ViewName);
}

3 Answers 3

4

If you pass a DefaultHttpContext to your controller, Request won't be null and you can assign the form to Request.Form. No mocking required.

[Xunit.Fact]
public async System.Threading.Tasks.Task SavePassNotEqualTest()
{
    var controller = new Controllers.PasswordRecoveryController(_mockRepo.Object);
    var dic = new System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues>();
    dic.Add("password", "test");
    dic.Add("password1", "test1");
    var collection = new Microsoft.AspNetCore.Http.FormCollection(dic);

    // Give the controller an HttpContext.
    controller.ControllerContext.HttpContext = new DefaultHttpContext();
    // Request is not null anymore.
    controller.Request.Form = collection;  

    var result = await controller.Save();
    var viewResult = Xunit.Assert.IsType<Microsoft.AspNetCore.Mvc.ViewResult>(result);
    Xunit.Assert.Equal("~/Views/Message.cshtml", viewResult.ViewName);
}
Sign up to request clarification or add additional context in comments.

Comments

3

With Moq, you can do it like this:

var httpContext = new Mock<HttpContextBase>();           

httpContext.Setup(c => c.Request.Form).Returns(delegate()
{
    var formVaues = new NameValueCollection();
    formVaues .Add("Id", "123");
    formVaues .Add("Name", "Smith");

    return formVaues ;
});

1 Comment

In ASP.NET Core it should be HttpContext, not HttpContextBase.
2

In Moq you can try to use Setup() or SetupGet() to teach it to return something that you need

something along the lines of

controller.SetupGet(x => x.Request.Form).Returns(collection);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.