Search code examples
javaeclipseunit-testingtestngtestcase

Write unit tests with TestNG in Eclipse


The class MobileStorage is the implementation of a retro mobile phone's inbox. The inbox thereby is de ned to hold a prede ned maximum capacity of messages with up to 160 characters per message. The following operations are supported and need to be tested:

  1. saveMessage: Stores a new text message to the inbox at the next free position. In case the message text is longer than 160 characters, the message is splitted and stored on multiple storage positions.
  2. deleteMessage: Removes the oldest ( rst) mobile message from the inbox.
  3. listMessages: Prints a readable representation of all currently stored messages. Messages that were stored in multiple parts are joined together for representation.

I need to do some Unit Testing on this code that i attached. Im not very familiar with TestNG and unit testing in general, can you help me with some examples of testing that i can do?

mobile_storage\src\main\java\MobileMessage.java - https://pastebin.com/RxNcgnSi

/**
 * Represents a mobile text message.
 */
public class MobileMessage {
    //stores the content of this messages
    private final String text;

    //in case of multi-part-messages, stores the preceding message
    //is null in case of single message
    private MobileMessage predecessor;

    public MobileMessage(String text, MobileMessage predecessor) {
        this.text = text;
        this.predecessor = predecessor;
    }

    public String getText() {
        return text;
    }

    public MobileMessage getPredecessor() {
        return predecessor;
    }

    public void setPredecessor(MobileMessage predecessor) {
        this.predecessor = predecessor;
    }
}

mobile_storage\src\main\java\MobileStorage.java - https://pastebin.com/wuqKgvFD

import org.apache.commons.lang.StringUtils;

import java.util.Arrays;
import java.util.Objects;
import java.util.stream.IntStream;

/**
 * Represents the message inbox of a mobile phone.
 * Each storage position in the inbox can store a message with 160 characters at most.
 * Messages are stored with increasing order (oldest first).
 */
public class MobileStorage {

    final static int MAX_MESSAGE_LENGTH = 160;

    private MobileMessage[] inbox;
    private int occupied = 0;

    /**
     * Creates a message inbox that can store {@code storageSize} mobile messages.
     * @throws IllegalArgumentException in case the passed {@code storageSize} is zero or less
     */
    public MobileStorage(int storageSize) {
        if(storageSize < 1) {
            throw new IllegalArgumentException("Storage size must be greater than 0");
        }

        this.inbox = new MobileMessage[storageSize];
    }

    /**
     * Stores a new text message to the inbox.
     * In case the message text is longer than {@code MAX_MESSAGE_LENGTH}, the message is splitted and stored on multiple storage positions.
     * @param message a non-empty message text
     * @throws IllegalArgumentException in case the given message is empty
     * @throws RuntimeException in case the available storage is too small for storing the complete message text
     */
    public void saveMessage(String message) {
        if(StringUtils.isBlank(message)) {
            throw new IllegalArgumentException("Message cannot be null or empty");
        }

        int requiredStorage = (int) Math.ceil((double) message.length() / MAX_MESSAGE_LENGTH);

        if(requiredStorage > inbox.length || (inbox.length - occupied) <= requiredStorage) {
            throw new RuntimeException("Storage Overflow");
        }

        MobileMessage predecessor = null;
        for(int i = 0; i < requiredStorage; i++) {
            int from = i * MAX_MESSAGE_LENGTH;
            int to = Math.min((i+1) * MAX_MESSAGE_LENGTH, message.length());

            String messagePart = message.substring(from, to);
            MobileMessage mobileMessage = new MobileMessage(messagePart, predecessor);
            inbox[occupied] = mobileMessage;
            occupied++;
            predecessor = mobileMessage;
        }
    }

    /**
     * Returns the number of currently stored mobile messages.
     */
    public int getOccupied() {
        return occupied;
    }

    /**
     * Removes the oldest (first) mobile message from the inbox.
     *
     * @return the deleted message
     * @throws RuntimeException in case there are currently no messages stored
     */
    public String deleteMessage() {
        if(occupied == 0) {
            throw new RuntimeException("There are no messages in the inbox");
        }

        MobileMessage first = inbox[0];

        IntStream.range(1, occupied).forEach(index -> inbox[index-1] = inbox[index]);
        inbox[occupied] = null;
        inbox[0].setPredecessor(null);
        occupied--;

        return first.getText();
    }

    /**
     * Returns a readable representation of all currently stored messages.
     * Messages that were stored in multiple parts are joined together for representation.
     * returns an empty String in case there are currently no messages stored
     */
    public String listMessages() {
        return Arrays.stream(inbox)
                .filter(Objects::nonNull)
                .collect(StringBuilder::new, MobileStorage::foldMessage, StringBuilder::append)
                .toString();
    }

    private static void foldMessage(StringBuilder builder, MobileMessage message) {
        if (message.getPredecessor() == null && builder.length() != 0) {
            builder.append('\n');
        }
        builder.append(message.getText());
    }
}

Solution

  • You will have to set up testNG . The way I test with testNG is with Eclipse and maven (dependency management). Once you have that , you can import classes in a test.java file in src folder under maven-Java project of eclipse.

    You may need to adjust the code and import necessary classes for testNG. Here is the official documentation of testNG and here is the assert class.

    I have tried to include some test cases. Hope this helps

    Your test.java may look something like this

            import yourPackage.MobileStorage;
            import yourPackage. MobileMessage;
    
            public class test{
    
            @BeforeTest
            public void  prepareInstance(){
    
                MobileStorage mobStg = new MobileStorage();
                MobileMessage mobMsg = new MobileMessage();
            }
    
            //test simple msg
            @Test
            public void  testSave(){
    
              mobStg.saveMessage("hello")
              assert.assertEquals("hello", mobMsg.getText())
            }
    
            //test msg with more chars
            @Test
            public void  testMsgMoreChar(){
                 mobStg.saveMessage("messageWithMoreThan160Char")
    
                 //access messagepart here somehow, i am not sure of that
                  assert.assertEquals(mobMsg.getText(), mobStg.messagePart);
    
                 //access message here somehow. This will test listMessages() and concatenation of msgs
                 assert.assertEquals(mobStg.message, mobStg.listMessages())   
            }
    
     //test deletion of msg   
    @Test    
    public void  testDelete(){
                 mobStg.deleteMessage();
                  assert.assertEquals(null, mobMsg.getPredecessor()) 
            }
    
    
    
        }