I'm trying to unit test the MembershipProvider, however I cant figure out how or whether there is any need for unit testing of it...
My business layer:
public interface IAccountService
{
MembershipCreateStatus CreateUser(string userName, string password, string email);
}
public class AccountService : IAccountService
{
private readonly MembershipProvider provider;
public AccountService() : this(null) { }
public AccountService(MembershipProvider providera)
{
this.provider = providera ?? Membership.Provider;
}
public MembershipCreateStatus CreateUser(string userName, string password, string email)
{
if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", userName);
if (String.IsNullOrEmpty(password)) throw new ArgumentException("Value cannot be null or empty.", password);
if (String.IsNullOrEmpty(email)) throw new ArgumentException("Value cannot be null or empty.", email);
MembershipCreateStatus status;
provider.CreateUser(userName, password, email, null, null, true, null, out status);
return status;
}
}
The only examples I've found so far requires a "MockMembershipProvider" with a local database setup... seems quite odd to me.
Thanks in advance.
Having a "MockMembershipProvider with a local database setup" is odd for a few reasons.
Typically you do not want to unit test data access code. Your unit tests should run very quick, and be run often, and thus not require database access. This is why you should be able to mock your data access tier. Persisting data would be acceptable for integration testing, but typically not unit testing.
The rest of this answer is based on the assumption that you do not want to hit the DB in your unit test.
Whether you wish to unit test the membership provider will depend on what is going on in there.
If the membership provider is custom written and contains business logic then it should be unit tested. If this is the case you need to create a mock DAO object within the membership provider so that the membership provider can be exercised by unit tests without hitting the database.
If the membership provider is simply carrying out database access (either directly or with call forwarding to the data access tier), you should not unit test it. If you are using the Microsoft asp.net membership provider you also should not test it.
Instead you should create a mock MembershipProvider
to use within the AccountService
class. You will inject the mock using constructor injection, this is the purpose of the following boilerplate code
public AccountService() : this(null) { }
public AccountService(MembershipProvider providera)
{
this.provider = providera ?? Membership.Provider;
}
This code facilitates constructor injection of alternative implementations (which includes mocks). An example of what a test might look like:
[Test]
public void ExampleTestWithAHandRolledMock()
{
//arrange
var mockMembershipProvider = new MockMembershipProvider();//no db access in this mock implementation
var accountService = new AccountService(mockMembershipProvider);
//act
accountService.CreateUser("foo", "bar", "baz");
//assert
Assert.IsTrue(mockMembershipProvider.MockUserExists("foo","bar","baz");//added a method to mock to confirm user was added
}
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