Your Unit test of the controller should not use your CustomMembershipProvider or the standard SQL provider. If performing a Unit test you should use a Stub/Fake that you have complete control over what it's returning. If you're using the real provider in the test it's no longer a Unit test, it's an integration test.
In order to achieve Unit testability you need to define a Fake provider, either using a Mocking framework or by hand rolling a fake with "canned" results. The fake could look something like this:
public class FakeMembershipProvider : MembershipProvider
{
public MembershipCreateStatus CreateStatus = MembershipCreateStatus.Success;
public void CreateUser((string username, string password, string email,
string passwordQuestion, string passwordAnswer, bool isApproved,
object providerUserKey, out MembershipCreateStatus status)
{
status = CreateStatus;
}
...
}
Let the controller take the provider as a ctor argument
public class AccountController
{
private readonly MembershipProvider _membershipProvider;
public AccountController(MembershipProvider membershipProvider)
{
_membershipProvider = membershipProvider;
}
public ActionResult Register(RegistrationModel model)
{
MembershipCreateStatus result;
_membershipProvider.CreateUser(model.Email, model.Password, ..., out result);
return View(/*Make this depend on the result*/);
}
}
In the Unit test you want to setup the fake according to what you want to test and you can assert the outcome that you expect for each registration result:
[Test]
void Should_display_success_view_when_user_successfully_created()
{
var membershipProvider = new FakeMembershipProvider();
membershipProvider.CreateStatus = MembershipCreateStatus.Success;
var controller = new AccountController(membershipProvider);
var model = new RegistrationModel();
var result = controller.Register(model) as ViewResult;
Assert.That(result.Name, Is.EqualTo("ExpectedViewName"));
}
Since the MemberShipProvider is quite large and you're probably not going to use all of it it can be wise to use @SteveWilkes approach of wrapping the Membership class instead to create a smaller more targeted interface. Also a mocking framework save you a lot of work. In order to wire up your controller with the new dependency you have to create a new ControllerFactory.