Note that there are some explanatory texts on larger screens.

plurals
  1. POUnit testing custom MembershipProvider.ValidateUser, using code in Global.asax
    primarykey
    data
    text
    <p>I have a unit test to check my AccountController.LogIn method. A redirect result is returned to indicate successs, otherwise a viewresult is returned.</p> <p>The test always fails as the return type is always viewresult, even though the test should return success as the credentials are valid, however I can't identify where the problem is. My TestMethod: <strong>CustomerRepositoryTest.cs</strong></p> <pre><code>[TestMethod] public void Can_Login_With_Valid_Credentials() { // Arrange Mock&lt;IAddressRepository&gt; mockAddressRepository = new Mock&lt;IAddressRepository&gt;(); Mock&lt;ICustomerRepository&gt; mockCustomerRepository = new Mock&lt;ICustomerRepository&gt;(); Mock&lt;IOrderRepository&gt; mockOrderRepository = new Mock&lt;IOrderRepository&gt;(); LoginViewModel model = new LoginViewModel { Email = "me@5.com", Password = "password" }; AccountController target = new AccountController(mockCustomerRepository.Object, mockAddressRepository.Object, mockOrderRepository.Object); // Act ActionResult result = target.LogIn(model); // Assert Assert.IsInstanceOfType(result, typeof(RedirectResult)); Assert.AreEqual("", ((RedirectResult)result).Url); } </code></pre> <p>When I run the test, it fails in My AccountController Login method when I call ValidateUser <strong>AccountController.cs</strong></p> <pre><code>if (Membership.ValidateUser(LoginModel.Email, LoginModel.Password)) { ... return RedirectToRoute(new { controller = "Account", action = "Details" }); } else { return View(); } </code></pre> <p>My custom MembershipProvider ValidateUser looks like this:</p> <p><strong>AccountMembershipProvider.cs</strong></p> <pre><code>public class AccountMembershipProvider : MembershipProvider { [Inject] public ICustomerRepository repository { get; set; } public override bool ValidateUser(string username, string password) { var cust = repository.GetAllCustomers().SingleOrDefault.. </code></pre> <p>When I run the application normally i.e. not testing, the login works fine. In the application I inject the CustomerRepository into the custom membership provider in <strong>Global.asax</strong>:</p> <pre><code> public class MvcApplication : System.Web.HttpApplication { private IKernel _kernel = new StandardKernel(new MyNinjectModules()); internal class MyNinjectModules : NinjectModule { public override void Load() { Bind&lt;ICustomerRepository&gt;().To&lt;CustomerRepository&gt;(); } } protected void Application_Start() { _kernel.Inject(Membership.Provider); ... </code></pre> <p>Is it the case that the Global.asax code isn't run while unit testing? and so my custom provider isn't being injected, hence the fail?</p> <p><strong>UPDATE</strong> I mocked my Provider class and passed the mocked CustomerRepository object to it.</p> <pre><code>Mock&lt;AccountMembershipProvider&gt; provider = new Mock&lt;AccountMembershipProvider&gt;(); provider.Object.repository = mockCustomerRepository.Object; </code></pre> <p>I then created a setup for the method I'm trying to test:</p> <pre><code> mockCustomerRepository.Setup(m =&gt; m.IsValidLogin("me@5.com", "password")).Returns(true); </code></pre> <p>But unfortunately I'm still getting a fail every time. To answer the question about whether I need a real or mocked object for the test - I'm not fussy, I just want to get it working at the moment!</p> <p><strong>UPDATE 2</strong></p> <p>I made those changes, and while it's still failing, it has allowed me to identify the specific problem. While debugging the test, I discovered that when I call the overridden</p> <pre><code>Membership.ValidateUser(LoginModel.Email, LoginModel.Password) </code></pre> <p>The Membership.Provider is of type SqlMembershipProvider (which is presumably the default type) and consequently validation fails.</p> <p>If I cast the provider to my custom provider...</p> <pre><code>((AccountMembershipProvider)Membership.Provider).ValidateUser(LoginModel.Email, LoginModel.Password) </code></pre> <p>I get an InvalidCastException when running the test. So it seems that my mocked AccountMembershipProvider isn't being used for the test and instead the default provider is being used.</p> <p>I think you have identified this already in the comment:</p> <pre><code>// set your mock provider in your AccountController </code></pre> <p>However I'm not sure what you mean exactly - I don't have a property on my AccountController to assign the provider to, and i'm not injecting it into the constructor.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload