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.", userN开发者_Go百科ame);
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 theAccountService
class. You will inject the mock using constructor injection, this is the purpose of the following boilerplate codepublic 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 }
精彩评论