Connor Gervin
Connor Gervin

Reputation: 946

Unit Testing account MVC controller Error - real MembershipService is still being used

I have the following account controller

public class AccountController : Controller
{

    public IMembershipService MembershipService { get; set; }

    protected override void Initialize(RequestContext requestContext)
    {
        if (MembershipService == null) { MembershipService = new AccountMembershipService(); }

        base.Initialize(requestContext);
    }

    public AccountController(IMembershipService membership)
    {
        MembershipService = membership;
    }

  [HttpPost]
    public ActionResult Login(LoginModel model, string ReturnUrl)
    {
        if (ModelState.IsValid)
        {
            if (MembershipService.ValidateUser(model.EmailorUserName, model.Password))
            {
            .....
            }
        }
   }

from my unit testing project I want to simulate a login

public class AccountControllerTest2
{
    [Test]
    public void Login_UserCanLogin()
    {
        string returnUrl = "/Home/Index";
        string userName = "user1";
        string password = "password1";

        Mock<AccountMembershipService> Membership = new Mock<AccountMembershipService>();
        AccountController Controller = new AccountController(Membership.Object);

        var model = new LoginModel
        {
            EmailorUserName = userName,
            Password = password
        };

        var result = Controller.Login(model, returnUrl) as RedirectResult;

        Assert.NotNull(result);
        Assert.AreEqual(returnUrl, result.Url);
    }
}

my web config in my main application uses custommembership provider

<membership defaultProvider="CustomMembershipProvider">
  <providers>
    <clear />
    <add name="CustomMembershipProvider" type="QUBBasketballMVC.Infrastructure.CustomMembershipProvider" connectionStringName="UsersContext" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
  </providers>
</membership>

I keep getting this error

QUBBasketballMVC.Tests.Controllers.AccountControllerTest.Login_UserCanLogin: System.Web.Management.SqlExecutionException : An error occurred during the execution of the SQL file 'InstallCommon.sql'. The SQL error number is 5123 and the SqlException message is: CREATE FILE encountered operating system error 5(Access is denied.) while attempting to open or create the physical file 'C:\PROGRAM FILES (X86)\NUNIT 2.6.3\BIN\APP_DATA\ASPNETDB_TMP.MDF'. CREATE DATABASE failed. Some file names listed could not be created. Check related errors. Creating the ASPNETDB_7b94db5a0b5b4fbbbe22fa8e91e4cc68 database...

Upvotes: 1

Views: 487

Answers (1)

StuartLC
StuartLC

Reputation: 107357

It seems that you are still initializing the real membership database, meaning that the MembershipService hasn't been completely mocked out. You shouldn't need to add the membership config to your unit tests, given that you intend mocking it out completely.

You almost certainly want to mock the Interface to your service abstraction IMembershipService, viz:

    Mock<IMembershipService> Membership = new Mock<IMembershipService>();

As an aside, the lazy initialization code

if (MembershipService == null) 
   MembershipService = new AccountMembershipService();

isn't ideal from a testing point of view, given that it means that the controller has 2 modes of operation, whereby it can either create the MembershipService itself, or accept one as a constructor dependency.

As an alternative, you might consider an IoC framework here to manage dependency lifespans, and this way there is only one set of code to be tested.

Upvotes: 1

Related Questions