Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: test System output including "new lines" with assertEquals

I'm currently writing a Unit Test for the Strategy Design Pattern. I'm comparing the System output with a string in the assertEquals method.The output looks the same but my test keeps failing.. . I'm thinking that I'm forgetting something to do with new lines or tabs?

My Unit Test:

import static org.junit.Assert.*;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class MiniDuck1Test {

    private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
    private final ByteArrayOutputStream errContent = new ByteArrayOutputStream();

    @Before
    public void setUpStreams() {
        System.setOut(new PrintStream(outContent));
        System.setErr(new PrintStream(errContent));
    }

    @After
    public void cleanUpStreams() {
        System.setOut(null);
        System.setErr(null);
    }

    @Test
    public void testDuck1() {       
        Duck mallard = new MallardDuck();
        mallard.performQuack();
        mallard.performFly();

        Duck model = new ModelDuck();
        model.performFly();
        model.setFlyBehavior(new FlyRocketPowered());
        model.performFly();

        assertEquals("Quack\nI'm flying!!\nI can't fly\nI'm flying with a rocket", outContent.toString().trim());
    }
}

Output (second and third line appear red):

Quack
I'm flying!!
I can't fly
I'm flying with a rocket

Edit:

The quickest solution seemed to be adding an "\r" in front of my "\n". Multiple answers informed me that this needs to be done for Windows. After applying this my assertEquals looked like:

assertEquals("Quack\r\nI'm flying!!\r\nI can't fly\r\nI'm flying with a rocket", outContent.toString().trim());

Also: I forgot to mention that most of the code came from the book: "Head First Design Patterns" by Eric Freeman, Elisabeth Robson, Bert Bates and Kathy Sierra.

like image 505
Wouter Vanherck Avatar asked Jan 16 '17 10:01

Wouter Vanherck


People also ask

Can you have multiple assertEquals in one test?

Yes it is possible to have more than one assertEquals in one unittest. The unit test fails if one of the assertEquals returns false.

What does assertEquals return in Java?

assertEquals. Asserts that two object arrays are equal. If they are not, an AssertionError is thrown. If expected and actual are null , they are considered equal.

What does assertEquals return?

assertEqual() in Python is a unittest library function that is used in unit testing to check the equality of two values. This function will take three parameters as input and return a boolean value depending upon the assert condition. If both input values are equal assertEqual() will return true else return false.

What does the assertTrue () method do?

assertTrue is used to verify if a given Boolean condition is true. This assertion returns true if the specified condition passes, if not, then an assertion error is thrown.


1 Answers

In addition to the other answers if you are looking for a platform-independent way...

A quick platform-independent solution can be to replace the line separators

String expected = "Quack\nI'm flying!!\nI can't fly\nI'm flying with a rocket"
                       .replaceAll("\\n|\\r\\n", System.getProperty("line.separator"));
assertEquals(expected, outContent.toString().trim());

or using a PrintWriter to build the expected string.

StringWriter expectedStringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(expectedStringWriter);

printWriter.println("Quack");
printWriter.println("I'm flying!!");
printWriter.println("I can't fly");
printWriter.println("I'm flying with a rocket");
printWriter.close();

String expected = expectedStringWriter.toString();
assertEquals(expected, outContent.toString());

or create an own assert class to re-use it

class MyAssert {

    public static void assertLinesEqual(String expectedString, String actualString){
        BufferedReader expectedLinesReader = new BufferedReader(new StringReader(expectedString));
        BufferedReader actualLinesReader = new BufferedReader(new StringReader(actualString));

        try {
            int lineNumber = 0;

            String actualLine;
            while((actualLine = actualLinesReader.readLine()) != null){
                String expectedLine = expectedLinesReader.readLine();
                Assert.assertEquals("Line " + lineNumber, expectedLine, actualLine);
                lineNumber++;
            }

            if(expectedLinesReader.readLine() != null){
                Assert.fail("Actual string does not contain all expected lines");
            }
        } catch (IOException e) {
            Assert.fail(e.getMessage());
        } finally {
            try {
                expectedLinesReader.close();
            } catch (IOException e) {
                Assert.fail(e.getMessage());
            }
            try {
                actualLinesReader.close();
            } catch (IOException e) {
                Assert.fail(e.getMessage());
            }
        }
    }
}

Then you can give a better problem description if the test fails. E.g.

MyAssert.assertLinesEqual(
         "Quack\nI'm flying!!\nI can not fly\nI'm flying with a rocket\n",
         outContent.toString());

will output

org.junit.ComparisonFailure: Line 2 
Expected :I can not fly
Actual   :I can't fly
like image 192
René Link Avatar answered Sep 21 '22 05:09

René Link