Hi i'm doing some unit test on my ASP.Net MVC2 project. I'm using Moq framework. In my LogOnController,
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl = "")
{
FormsAuthenticationService FormsService = new FormsAuthenticationService();
FormsService.SignIn(model.UserName, model.RememberMe);
}
In FormAuthenticationService class,
public class FormsAuthenticationService : IFormsAuthenticationService
{
public virtual void SignIn(string userName, bool createPersistentCookie)
{
if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
}
public void SignOut()
{
FormsAuthentication.SignOut();
}
}
My problem is how can i avoid executing
FormsService.SignIn(model.UserName, model.RememberMe);
this line. Or is there any way to Moq
FormsService.SignIn(model.UserName, model.RememberMe);
using Moq framework without changing my ASP.Net MVC2 project.
You can use Moq to create mock objects that simulate or mimic a real object. Moq can be used to mock both classes and interfaces. However, there are a few limitations you should be aware of. The classes to be mocked can't be static or sealed, and the method being mocked should be marked as virtual.
Moq supports mocking protected methods. Changing the methods to protected , instead of private , would allow you to mock their implementation.
Moq is a mocking framework built to facilitate the testing of components with dependencies. As shown earlier, dealing with dependencies could be cumbersome because it requires the creation of test doubles like fakes. Moq makes the creation of fakes redundant by using dynamically generated types.
The Moq framework is an open source unit testing framework that works very well with . NET code and Phil shows us how to use it.
Inject IFormsAuthenticationService
as a dependency to your LogOnController
like this
private IFormsAuthenticationService formsAuthenticationService;
public LogOnController() : this(new FormsAuthenticationService())
{
}
public LogOnController(IFormsAuthenticationService formsAuthenticationService) : this(new FormsAuthenticationService())
{
this.formsAuthenticationService = formsAuthenticationService;
}
The first constructor is for the framework so that the correct instance of IFormsAuthenticationService
is used at runtime.
Now in your tests create an instance of LogonController
using the other constructor by passing mock as below
var mockformsAuthenticationService = new Mock<IFormsAuthenticationService>();
//Setup your mock here
Change your action code to use the private field formsAuthenticationService
as below
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl = "")
{
formsAuthenticationService.SignIn(model.UserName, model.RememberMe);
}
Hope this helps. I have left out the mock setup for you. Let me know if you are not sure how to set that up.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With