-1

For a homework assignment, I have created a Class called Bird, that contains a method:

public void launch()
{
     System.out.println("Flapping the wings until take-off");
}

I need to run jUnit tests on all contained methods, including ones like these. However, when I use:

@Test
    void testLaunch()
    {
        Bird myBird = new Bird("Macaw");
        assertEquals("Flapping the wings to take-off", myBird.launch());
    }

I'm given this error in Eclipse: "The method assertEquals(short, short) in the type Assertions is not applicable for the arguments (String, void)"

I'm becoming frustrated because our teacher has not taught us how to test these kinds of methods, and he never answers my emails for assistance. Even if this is considered an overall weak question, any help would be greatly appreciated.

2 Answers2

1

You can use System.setOut(PrintStream) to temporarily replace standard out with an in memory PrintStream backed by a ByteArrayOutputStream and use that to get the output. Something like,

@Test
void testLaunch() {
    PrintStream original = System.out;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PrintStream tps = new PrintStream(baos);
    Bird myBird = new Bird("Macaw");
    System.setOut(tps);
    myBird.launch();
    System.setOut(original);
    tps.flush();
    assertEquals("Flapping the wings to take-off", baos.toString());
}
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • This fixed the issue for now. I'll have to ask my teacher what exactly this all means when I get to class and see what he had in mind for us to do in his head. Was about to just have the methods return a String, but the instructions state it has to be a void method. Thanks so much for your help! – thundafellow Feb 21 '20 at 06:55
0

Usually you only test methods that have some kind of logic in them. Calling System.out.println is not considered logic.

From a a test driven point of view it's easier to work with methods that are side-effect-free, as in they take some parameters and return a result, your method is quite the opposite and thus very hard to test.

The only viable approach in your case (beside stating that your method isn't complicated egnough to be tested) is to split your method into one that creates the String (that method can be tested) and one that calls the other method and prints the result (calling anouther method (in another class called a service) is testable with a variety of frameworks (Mockito for example). Calling System.out.println is very hard to test, you could extract a Supplier for the Stream (System.out) and verify it returns indeed System.out and again verify that println is called on the supplied Stream.

Looking at this test structure points out the fact, that the base method is not only relying on side effects but it's also doing three things at once (whereas ideal methods do only one thing). it creates an Object (here a String), it acquires and OutStream (here System.out) and it uses both together (println).

Yes, this might seem overly complicated but from a learning point of view it shows that even hidden in something as simple as this, there is a lot of complexity and if done right can teach a lot about object oriented design and clean and S.O.L.I.D. code

Nicktar
  • 5,548
  • 1
  • 28
  • 43