I would like ot test my MVC controllers. They arent simple , I have ActionResult that returns a View, But there is alot of code before the View is returned.
For example I call
public ActionResult Login(string returnUrl)
{
EnsureLoggedOut();
var viewModel = new AccountLoginModel
{
ReturnUrl = returnUrl
};
return View(viewModel);
}
When i try to run a simple test it calls EnsureLoggedOut, which in turn looks for a Request Object which is null. (do i need to Mock that ?).
I want to test this ActionMethod such that it returns what it is meant to ..
Is there examples on how to do this or a framework that can help
using request object directly will make testing harder. you will need to mock it in routines that use it. in you sample code it would make more sense to make EnsureLoggedOUt() mockable. make it settable property, with a default implementation.
public Action EnsureLoggedOut = () =>
{
...
};
then in the unit test replace it with a mocked version
[TestMethod]
public void GetActionReturnsCustomerAsJson()
{
CustomerController controller = new CustomerController();
JsonResult result = controller.GetCustomer() as JsonResult;
// todo add asserts here.
}
Now when i debug the testmethod above, it calls the following controller code:
[HttpPost]
public ActionResult GetCustomer()
{
var customer = Customer.Get();
return Json(new { success = string.IsNullOrEmpty(customer.Error), customer = customer });
}
When it calls: var customer = Customer.Get(); it then goes to code below:
But I have a set Customeid and url that I know and the resultant Customer object that I expect to be returned, but what I cant exactly figure out is if I let the
code step through while debugging GetCustomer doesnt take any inputs , nor does the Get , how can i pass these in ? Also when i get to call Get , Session is null ,
how can i overcome this ?
Do i need to set an Initialise routine in my tests ?
public static Customer Get()
{
var customerId = Principal.Current.ClientId; <-------This i know I can pass in, but how since there are no input parameters ?
var setup = SessionFactory.GetSetup(); <-------This get the db connnection string , do I need to Mock ?
var authUrl = setup?.AuthenticationUrl ?? ConfigurationManager.AppSettings.GetValues("AuthenticationServer").First(); <-----I actually know the URL required .
HttpWebRequest request = (HttpWebRequest)WebRequest.Create($"{authUrl}customer/{customerId}"); <------This I know from the above URL.
request.Method = "GET";
var response = request.GetResponse();
var responseJson = string.Empty;
using (var stream = response.GetResponseStream())
{
using (var rdr = new StreamReader(stream))
{
responseJson = rdr.ReadToEnd();
}
}
if (string.IsNullOrEmpty(responseJson))
{
return new Customer { Error = "No record located." };
}
var customer = JsonConvert.DeserializeObject<Customer>(responseJson);
if (customer != null)
return customer;
return new Customer { Error = "No record located." };
}
So basically all I want back is Customer object and I can check what is returned against what I expect.
Member
280 Points
1000 Posts
How can i test my MVC Controllers ?
Apr 16, 2019 06:41 AM|robby32|LINK
Hi ,
I would like ot test my MVC controllers. They arent simple , I have ActionResult that returns a View, But there is alot of code before the View is returned.
For example I call
public ActionResult Login(string returnUrl)
{
EnsureLoggedOut();
var viewModel = new AccountLoginModel
{
ReturnUrl = returnUrl
};
return View(viewModel);
}
When i try to run a simple test it calls EnsureLoggedOut, which in turn looks for a Request Object which is null. (do i need to Mock that ?).
I want to test this ActionMethod such that it returns what it is meant to ..
Is there examples on how to do this or a framework that can help
Thanks
All-Star
57844 Points
15487 Posts
Re: How can i test my MVC Controllers ?
Apr 16, 2019 02:07 PM|bruce (sqlwork.com)|LINK
using request object directly will make testing harder. you will need to mock it in routines that use it. in you sample code it would make more sense to make EnsureLoggedOUt() mockable. make it settable property, with a default implementation.
public Action EnsureLoggedOut = () =>
{
...
};
then in the unit test replace it with a mocked version
Member
280 Points
1000 Posts
Re: How can i test my MVC Controllers ?
Apr 17, 2019 04:55 AM|robby32|LINK
Hi ,
I not understanding exactly what you mean
Maybe I can show with this ..
I have a test method as follows:
[TestMethod]
public void GetActionReturnsCustomerAsJson()
{
CustomerController controller = new CustomerController();
JsonResult result = controller.GetCustomer() as JsonResult;
// todo add asserts here.
}
Now when i debug the testmethod above, it calls the following controller code:
[HttpPost]
public ActionResult GetCustomer()
{
var customer = Customer.Get();
return Json(new { success = string.IsNullOrEmpty(customer.Error), customer = customer });
}
When it calls: var customer = Customer.Get(); it then goes to code below:
But I have a set Customeid and url that I know and the resultant Customer object that I expect to be returned, but what I cant exactly figure out is if I let the
code step through while debugging GetCustomer doesnt take any inputs , nor does the Get , how can i pass these in ? Also when i get to call Get , Session is null ,
how can i overcome this ?
Do i need to set an Initialise routine in my tests ?
public static Customer Get()
{
var customerId = Principal.Current.ClientId; <-------This i know I can pass in, but how since there are no input parameters ?
var setup = SessionFactory.GetSetup(); <-------This get the db connnection string , do I need to Mock ?
var authUrl = setup?.AuthenticationUrl ?? ConfigurationManager.AppSettings.GetValues("AuthenticationServer").First(); <-----I actually know the URL required .
HttpWebRequest request = (HttpWebRequest)WebRequest.Create($"{authUrl}customer/{customerId}"); <------This I know from the above URL.
request.Method = "GET";
var response = request.GetResponse();
var responseJson = string.Empty;
using (var stream = response.GetResponseStream())
{
using (var rdr = new StreamReader(stream))
{
responseJson = rdr.ReadToEnd();
}
}
if (string.IsNullOrEmpty(responseJson))
{
return new Customer { Error = "No record located." };
}
var customer = JsonConvert.DeserializeObject<Customer>(responseJson);
if (customer != null)
return customer;
return new Customer { Error = "No record located." };
}
So basically all I want back is Customer object and I can check what is returned against what I expect.
Thanks