user3549524
user3549524

Reputation: 227

How to mock a method within an action method in ASP.NET MVC?

I want to mock (with MOQ) the method CheckCredentials which is part of the LoginManager class.

public ActionResult Login(string username, string password)
            {
                if (lm.CheckCredentials(username, password) != 0)
                    return RedirectToAction("Index", "Login");

                return RedirectToAction("Index", "Home");
            }

Testmethod

public void TestMethod1()
    {
        Mock<LoginManager> mock = new Mock<LoginManager>();

        mock.Setup(x => x.CheckCredentials("", "")).Returns(0); 

        HomeController homeController = new HomeController();

        RedirectToRouteResult ar = homeController.Login("", "") as RedirectToRouteResult;
        ...
    }

Now my problem is that I don't really now how to correctly mock that method. I have seen YT videos where the mock objects are passed as parameters but isn't that quite bad if I have to change the parameters of a method just to be able to create a unit test? Is that the only way to do it or are there other possibilities?

Upvotes: 0

Views: 563

Answers (1)

Shyju
Shyju

Reputation: 218942

You need to extract an interface for your LoginManager class.

public interface ILoginManager
{
    int CheckCredentials(string userName, string password);
}

public class LoginManager : ILoginManager
{
    public int CheckCredentials(string userName, string password)
    {
        // your existing implementation.
    }
}

And inject an implementation of ILoginManager to your controller via constructor injection.

public class HomeController : Controller
{
    private ILoginManager loginManager;
    public HomeController(ILoginManager loginManager)
    {
        this.loginManager = loginManager;
    }
    public ActionResult Login(string userName,string password)
    {
        if (loginManager.CheckCredentials(username, password) != 0)
                return RedirectToAction("Index", "Login");

        return RedirectToAction("Index", "Home");
    }
}

and in your test, create a mocked version of the ILoginManager and mock the behavior using SetUp method.

public void TestMethod1()
{
    var mock = new Mock<ILoginManager>();

    mock.Setup(x => x.CheckCredentials("", "")).Returns(0);

    var homeController = new HomeController(mock.Object);

    var ar = homeController.ReportScore("") as RedirectToRouteResult;

    //TO DO : Assert something

}

Upvotes: 1

Related Questions