Open In App

Encode and Decode Strings in Java with JUnit Tests

Last Updated : 02 Jan, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Strings are very useful and they can contain sequences of characters and there are a lot of methods associated with Strings. Moreover, encoding and decoding are possible for a given use case and it can be validated whether are they equal or not for a given requirement. They can be tested for validity with JUnit as well. Given requirement for 

encode: 

  • Convert all the characters of the given string to Uppercase
  • Check for the first occurrence of ‘,’ and replace that with ‘.’
  • Similarly the last occurrence of ‘!’ and replace that with ‘.’

decode:

Bring back the original test string

Note:

For specific requirements, the code is written. Our task is to write the business logic and test the same with JUnit. 

Let’s do that via a Maven project that contains the dependency for JUnit.

Example Maven Project

Project Structure:

Project Structure

 

pom.xml

XML




<?xml version="1.0" encoding="UTF-8"?>
         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.StringServicesJava</groupId>
    <artifactId>StringServicesJava</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
 
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit.version>5.3.1</junit.version>
        <pitest.version>1.4.3</pitest.version>
    </properties>
 
    <dependencies>
 
        <!-- junit 5, unit test -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
 
    </dependencies>
    <build>
        <finalName>maven-mutation-testing</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M1</version>
            </plugin>
 
            <plugin>
                <groupId>org.pitest</groupId>
                <artifactId>pitest-maven</artifactId>
                <version>${pitest.version}</version>
 
                <executions>
                    <execution>
                        <id>pit-report</id>
                        <phase>test</phase>
                        <goals>
                            <goal>mutationCoverage</goal>
                        </goals>
                    </execution>
                </executions>
 
                <!-- https://github.com/hcoles/pitest/issues/284 -->
                <!-- Need this to support JUnit 5 -->
                <dependencies>
                    <dependency>
                        <groupId>org.pitest</groupId>
                        <artifactId>pitest-junit5-plugin</artifactId>
                        <version>0.8</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <targetClasses>
                        <param>com.gfg.StringServicesJava.*StringServicesJava*</param>
                    </targetClasses>
                    <targetTests>
                        <param>com.gfg.StringServicesJava.*</param>
                    </targetTests>
                </configuration>
            </plugin>
 
        </plugins>
    </build>
 
</project>


Let’s check the encode and decode method logic here. As informed to a specific scenario it is addressed.

StringEncodeDecodeServicesJava.java

Java




public class StringEncodeDecodeServicesJava {
    public static String encode(String message) {
        message = message.toUpperCase();
        for (int i = 0; i < message.length(); i++) {
            if (message.charAt(i) == ',') {
                message = message.replace(',', '.');
            }
            if (message.charAt(i) == '!') {
                message = message.replace('!', '.');
            }
        }
        return message;
    }
 
    public static String decode(String encodedMessage) {
        String decodedMessage = encodedMessage.substring(0, 1).toUpperCase()
                + encodedMessage.substring(1).toLowerCase();
        int count = 0;
 
        String newMessage = "";
 
        for (int i = 0; i < decodedMessage.length(); i++) {
            if (decodedMessage.charAt(i) == '.') {
                newMessage += decodedMessage.substring(0, i) + ",";
                count = i;
                break;
            }
        }
        for (int i = count + 1; i < decodedMessage.length(); i++) {
            if (decodedMessage.charAt(i) == '.') {
                newMessage += decodedMessage.substring(count + 1, i) + "!";
                count = i;
                break;
            }
        }
 
        return newMessage;
    }
 
    public static void main(String[] args) {
        String test = "Hello, this is fun!";
        String encoded = encode(test);
        //System.out.println("Encoded message : " + encoded);
        String decoded = decode(encoded);
        //System.out.println("Decoded message : " + decoded);
        if (decoded.equals(test)) {
            System.out.println("Success! At least for this example!");
        } else {
            System.out.println("Something went wrong!");
        }
    }
 
}


JUnit testing code with asserts

TestStringEncodeDecodeServicesJava.java

Java




package com.gfg.StringServicesJava;
 
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
 
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
 
public class TestStringEncodeDecodeServicesJava {
    @DisplayName("Test check for Encode and Decode")
    @Test
    public void testCheckForEncodeAndDecode() {
        String testStr = "Hello, this is fun!";
        String encodedStr = StringEncodeDecodeServicesJava.encode(testStr);
        System.out.println("Encoded message : " + encodedStr);
        String decodedStr = StringEncodeDecodeServicesJava.decode(encodedStr);
        System.out.println("Decoded message : " + decodedStr);
         
        // This yields true when decodedStr.equals(testStr)
        // and we are checking against true
        assertEquals(true, decodedStr.equals(testStr));
         
        // We are checking for true
        assertTrue(decodedStr.equals(testStr));
         
        // We are checking for false by adding !condition
        assertFalse(!decodedStr.equals(testStr));
        boolean[] expectedValues = { decodedStr.equals(testStr), "Hello, this is fun!".equals(testStr) };
        boolean[] actualValues = { true, true };
         
        // Sometimes there are possibilities to
        // combine more than one condition
        assertArrayEquals(expectedValues, actualValues);
         
        // Sometimes we need to go with assertAll because even
        // the first assert might have gone wrong but the rest are correct
        // During that time when we combine everything, even
        // if there is error it will indicate it
        assertAll("Should check whether encoding and decoding are correct",
                () -> assertEquals(true, decodedStr.equals(testStr)),
                () -> assertTrue(decodedStr.equals(testStr)),
                () -> assertArrayEquals(expectedValues, actualValues));
         
        assertAll("Should check whether encoding and decoding are correct by checking wrongly",
                () -> assertEquals(false, decodedStr.equals(testStr)),
                () -> assertFalse(decodedStr.equals(testStr)),
                () -> assertArrayEquals(expectedValues, actualValues));   
         
    }
}


Here we need to look carefully for assertAll. When we are writing the code, there are possibilities of producing wrong statements too and because of that if there is a chance of assert to get failed for the first statement, the rest of the statements will not execute at all. We can overcome that scenario by adding assertALL. As a group, it will check all the asserts that are present under assertAll and indicate the errors under one common heading. Here we have kept the heading as “Should check whether encoding and decoding are correct by checking wrongly”. After seeing the output, we can conclude that “assertAll” plays a good role

 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads