Tuesday, March 11, 2014

Parameterized JUnit tests

Sometimes you encounter a problem that just screams for using "parameterized" tests rather than copy/pasting the same method many times.   The test method is basically the same and the only thing that changes is the data passed in.  In this case, consider creating a test case that utilitizes the "Parameterized" class from JUnit.

I recently ran into a problem where our validation of an email address did not allow unicode characters.  The fix was fairly straight-forward, change the regular expression to allow those characters.  Next, it was time to test the change.  Rather than copy/paste separate methods for each set of data, I decided to learn about the Parameterized method.   Below is the result.  The data includes the expected result and the email address to be validated.

JUnit test class
package com.mycompany.client;

import static org.junit.Assert.*;

import java.util.Arrays;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import com.mycompany.test.TestServiceUtil;

/**
 * Parameterized test case for validating email addresses against a regular expression.
 * We need to allow unicode characters in the userid portion of the email address, so 
 * these test cases where created to help validate the validateEmailAddress method
 * in the FieldValidationController class.
 * 
 * @author mmiller
 *
 */
@RunWith(Parameterized.class)
public class TestFieldValiationController {

    @Parameters(name = "{index}: {1} is valid email address = {0}")
    public static Iterable data() {
        return Arrays.asList(new Object[][] { 
         { true, "john@mycomp.com" },           { true,  "john123@mycomp.com" },
         { true, "j+._%20_-brown@mycomp.com" }, { true,  "123@mycomp.com" },
         { false, "john brown@mycomp.com" },    { false, "123@mycomp" },
         { false, "john^brown@mycomp.com" },    { true , "1john@mycomp.com" },
         { false, "john#brown@mycomp.com" },    { false, "john!brown@mycomp.com" },
         { false, "john()brown@mycomp.com" },   { false, "john=brown@mycomp.com" },
         { true,  "johñ.brown@mycomp.com" },    { false, "john.brown@mycomp.coñ" },
         { true,  "johú@mycomp.com" },          { true,  "johíáó@mycomp.com" }
        });
    }
  
    private boolean expected;
    private String emailAddress;

    public TestFieldValiationController(boolean expected, String emailAddress) {
        this.expected = expected;
        this.emailAddress = emailAddress;
        TestServiceUtil.getInstance();
    }

    @Test
    public void validateEmail() {
        assertEquals(expected, FieldValidationController.getInstance().validateEmailAddress(emailAddress));
    }
}

Hope this helps!

No comments:

Post a Comment