views:

169

answers:

1

I have added functionality to the Accounts Controller -> Registration ActionValidateRegistation function to test for blanks in the user registration form. I now want to throw an error to the form if the email address the user entered is already in the system. I have added the function checking for the duplicate email address at the end of the ValidateRegistration function.

I use linq to query the database to create a list of users and check the email if it has already been used which works well during runtime. I have created a visual basic test with test the user object (username, password, etc.) for a duplicate email address during the Registation Action. How do you avoid the ValidateRegistration to query the database and creating a list of users (which is what I want during runtime), but rather feed ValidateRegistration with fake user objects during unit testing?

Sample code: Accounts Contoller

    public ActionResult Register(string username... string password...)
    {

            //Call the ValidateRegistration(string username... string password...);

            //Add user if ValidateRegistration checks have passed
    }

public ValidateRegistration(string username... string password...) { //Check username if blank // ModelState.AddModelError( username is blank)

//check password length // ModelState.AddModelError( password is too short message)

//List lstUsers = GetUsers(); //check if email address is already used // ModelState.AddModelError( email already used)

//How do I unit test the above email address check?

}

SampleCode: Units Tests

    public void RegisterPostReturnsViewIfFirstnameNotSpecified()
    {
        // Arrange
        AccountController controller = GetAccountController();

        // Act
        ViewResult result = (ViewResult)controller.Register(string username... string password...)

        // Assert
        Assert.AreEqual(6, result.ViewData["PasswordLength"]);
        Assert.AreEqual(See if error message is equal);
    }
A: 

You should look into "Dependency Injection" or "Inversion of Control". There are a number of popular IoC containers that will allow you to configure what types are created at runtime when you ask for a new object (database access layer [DAL] in your case).

With DI the basic premise is that you tell your controller to "use this DAL", rather than the controller deciding which DAL to use. With IoC, your unit tests configure which classes are created when someone asks it for a DAL, and your controller asks the container for a DAL.

A very good starting point for this is Martin Fowler's article.

Bernhard Hofmann