Open In App

Assert Regex Matches in JUnit

Last Updated : 22 Oct, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Unit testing is a critical aspect of software development, ensuring that individual components of the application function correctly. JUnit is one of the most widely used frameworks for writing and executing unit tests in Java applications. In many scenarios, particularly when dealing with user input, configuration values, or any string data, it can be essential to validate that these strings conform to the expected patterns. Regular expressions (regex) act as a powerful tool for this matching purpose.

In this article, we will explore how to assert that a given string matches a specified regex pattern using JUnit.

Prerequisites

  • Basic knowledge of Java and the JUnit framework.
  • Basic understanding of regex syntax and its usage.
  • Maven for dependency management.
  • JDK and IntelliJ IDEA installed on your system.

What is Regex?

Regular Expressions (regex) consist of a sequence of characters that specify patterns for searching within strings. They are utilized for:

  • Pattern Matching: Verifying whether a string complies with a designated format.
  • Data Validation: Ensuring inputs (like email addresses or phone numbers) follow required rules.
  • Data Extraction: Pulling specific data from strings.

Common Regex Patterns:

  • Email Validation: ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}$
  • Phone Number: ^\\+\\d{1,2}-\\d{3}-\\d{3}-\\d{4}$
  • Date Format (YYYY-MM-DD): \\d{4}-\\d{2}-\\d{2}

Why Use Regex Assertions in Unit Tests?

When writing unit tests, validating string inputs is crucial for ensuring the integrity of the application. Here are a few reasons why regex assertions are particularly useful:

  • Input Validation: Prevent invalid data from being processed further in the application.
  • Error Prevention: Catch potential bugs early by verifying that strings conform to the expected formats.
  • Data Integrity: Ensure that the data stored or processed by the application is valid, thereby maintaining overall data integrity.

How to Assert Regex Matches in JUnit

Let's explore various methods for asserting that a string matches a regex pattern in JUnit.

Method 1: Using assertTrue() with Pattern.matches()

The Pattern class in Java provides the method matches() that can be used to check if a given string matches the regex pattern. Here's how to do it in a JUnit test.

Example:

import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import java.util.regex.Pattern;

public class RegexTest {

@Test
public void testEmailFormat() {
String email = "[email protected]"; // Email string to validate
String emailRegex = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}$"; // Regex pattern for email

// Assert that the email matches the regex
assertTrue(Pattern.matches(emailRegex, email),
"The email format is invalid."); // Failure message
}
}

Explanation:

  • String email: The email string to validate.
  • String emailRegex: The regex pattern to match the email format.
  • Pattern.matches(): Checks if the entire string matches the given regex.
  • assertTrue(): Asserts that the result is true; if not, it provides the failure message.

Method 2: Using String.matches()

The String class provides the convenient method matches(), which can be used similarly to assert regex matches.

Example:

import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;

public class RegexTest {

@Test
public void testPhoneNumber() {
String phoneNumber = "+1-123-456-7890"; // Phone number string to validate
String phoneRegex = "^\\+\\d{1,2}-\\d{3}-\\d{3}-\\d{4}$"; // Regex pattern for phone number

// Assert that the phone number matches the regex
assertTrue(phoneNumber.matches(phoneRegex),
"The phone number format is incorrect."); // Failure message
}
}

Explanation:

  • String phoneNumber: The phone number string to validate.
  • String phoneRegex: The regex pattern to validate the phone number format.
  • phoneNumber.matches(phoneRegex): Returns true if the phone number matches the regex.
  • assertTrue(): Verifies the result of the matches() method.

Method 3: Using assertEquals() for More Control

For greater control over assertion messages, you can use assertEquals(). This method allows for more detailed error reporting.

Example:

import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;

public class RegexTest {

@Test
public void testZipCode() {
String zipCode = "12345"; // Zip code string to validate
String zipRegex = "\\d{5}"; // Regex pattern for zip code

boolean matches = zipCode.matches(zipRegex); // Check if matches the regex
assertEquals(true, matches, "The zip code should be exactly 5 digits."); // Failure message
}
}

Explanation:

  • boolean matches: Holds the result of the matches() call.
  • assertEquals(): Asserts that matches is true. If it is not, it provides a specific message indicating the failure.

Custom Assertion for Regex Matching

To improve readability and maintainability of the tests, consider creating a custom assertion method. This helps encapsulate the regex matching logic in one place.

Example:

import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;

public class RegexTest {

// Custom assertion method for regex matching
public static void assertMatchesRegex(String regex, String actual, String message) {
assertTrue(actual.matches(regex), message); // Assert that the string matches the regex
}

@Test
public void testCustomAssertion() {
String date = "2024-10-07"; // Date string to validate
String dateRegex = "\\d{4}-\\d{2}-\\d{2}"; // Regex pattern for date

// Use the custom assertion method
assertMatchesRegex(dateRegex, date, "The date format should be YYYY-MM-DD."); // Failure message
}
}

Explanation:

  • assertMatchesRegex(): A static method that takes the regex pattern, the actual string to test, and a message. It asserts that the string matches the regex.
  • Reuse: This method can be reused across multiple tests, promoting DRY (Don’t Repeat Yourself) principles in the code.

Implementation of Assert Regex Matches in JUnit

The simple example project demonstrates how to assert regex matches using JUnit in a Java application. This project validates user input for three different scenarios: 1. Email Validation, 2. Phone Number Validation, 3. Zip Code Validation.

Step 1: Create the Maven Project

Create a new Maven Project using IntelliJ IDEA. Choose the following options:

  • Name: regex-validation-junit
  • Build System: Maven

Click on the Create button.

Project Metadata

Project Structure

After the project creation done, set the file structure as shown in the below image:

Project Folder Structure

Step 2: Add Dependencies to pom.xml

Open pom.xml and add the following JUnit dependencies to the Maven project.

XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.gfg</groupId>
    <artifactId>regex-validation-junit</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <junit.version>5.8.2</junit.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
            </plugin>
        </plugins>
    </build>

</project>
  • GroupId and ArtifactId: These define the Maven project coordinates.
  • JUnit Dependencies: The dependencies for JUnit 5 (Jupiter) for unit testing.
  • Surefire Plugin: This is used to run tests during the build process.

Step 3: Implement the Code

InputValidator.java:

This class includes methods to validate email, phone number, and zip code using regex.

Java
package com.gfg;

import java.util.regex.Pattern;

public class InputValidator {
    
    // Validates email format
    public boolean validateEmail(String email) {
        String emailRegex = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}$"; // Regex pattern for email
        return Pattern.matches(emailRegex, email); // Check if email matches the regex
    }

    // Validates phone number format
    public boolean validatePhoneNumber(String phoneNumber) {
        String phoneRegex = "^\\+\\d{1,2}-\\d{3}-\\d{3}-\\d{4}$"; // Regex pattern for phone number
        return Pattern.matches(phoneRegex, phoneNumber); // Check if phone number matches the regex
    }

    // Validates zip code format
    public boolean validateZipCode(String zipCode) {
        String zipRegex = "\\d{5}"; // Regex pattern for zip code
        return Pattern.matches(zipRegex, zipCode); // Check if zip code matches the regex
    }
}

Explanation:

  • InputValidator Class: Contains three methods for validating email, phone numbers, and zip codes.
  • validateEmail(), validatePhoneNumber(), validateZipCode(): Each method uses regex patterns to validate the respective input formats.

Step 4: Main Class

The Main class is the entry point of the application. It creates an instance of InputValidator and calls its methods with example inputs.

Java
package com.gfg;

public class Main {
    public static void main(String[] args) {
        InputValidator validator = new InputValidator(); // Create an instance of InputValidator
        
        // Email Validation
        System.out.println("Email Validation:");
        System.out.println("[email protected]: " + validator.validateEmail("[email protected]")); 
        System.out.println("test.com: " + validator.validateEmail("test.com")); 
        
        // Phone Number Validation
        System.out.println("\nPhone Number Validation:");
        System.out.println("+1-123-456-7890: " + validator.validatePhoneNumber("+1-123-456-7890")); 
        System.out.println("1234567890: " + validator.validatePhoneNumber("1234567890")); 
        
        // Zip Code Validation
        System.out.println("\nZip Code Validation:");
        System.out.println("12345: " + validator.validateZipCode("12345")); 
        System.out.println("1234a: " + validator.validateZipCode("1234a")); 
    }
}
  • Main Class: Entry point that demonstrates the validation methods.
  • validateEmail(), validatePhoneNumber(), validateZipCode(): Calls these methods with sample inputs to validate their formats and prints the results.

InputValidatorTest.java:

This is the test class for the InputValidator. It contains JUnit test methods that validate the correctness of the validation methods using assertions.

Java
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

public class InputValidatorTest {

    InputValidator validator = new InputValidator(); // Create an instance of InputValidator

    @Test
    public void testValidateEmail() {
        assertTrue(validator.validateEmail("[email protected]"), "The email format is invalid."); // Valid email
        assertFalse(validator.validateEmail("test.com"), "The email format is invalid."); // Invalid email
    }

    @Test
    public void testValidatePhoneNumber() {
        assertTrue(validator.validatePhoneNumber("+1-123-456-7890"), "The phone number format is incorrect."); // Valid phone number
        assertFalse(validator.validatePhoneNumber("1234567890"), "The phone number format is incorrect."); // Invalid phone number
    }

    @Test
    public void testValidateZipCode() {
        assertTrue(validator.validateZipCode("12345"), "The zip code should be exactly 5 digits."); // Valid zip code
        assertFalse(validator.validateZipCode("1234a"), "The zip code should be exactly 5 digits."); // Invalid zip code
    }
}
  • InputValidatorTest Class: Contains test cases for the InputValidator methods.
  • assertTrue() and assertFalse(): Verify that the expected conditions hold true for the test cases, providing informative messages for test failures.

Step 5: Run the Application

After completing the project, run this and it will display the below output.

Output

Step 6: Running the Tests

To run the tests, execute the following maven command in the terminal:

mvn test

Output:

We should see the output indicating which tests passed of the project.

Test Output

In this example project, we demonstrated how to validate the strings using the regex patterns in the Java application with JUnit tests. Making it easy to manage and maintain. Using the regex assertions in the unit tests helps ensure that the data handled by the application meets the required formats and standards.


Next Article
Article Tags :

Similar Reads