leoOrion leoOrion - 3 months ago 30
Java Question

Mocking console using mockito

I am printing the list of books from a library using a printBooks operation class. I want to see if the proper output is written to console.
This is what I have tried so far. Can someone please explain what Im doing wrong here. Thanks in advance.

PrintBooksOperation.java

package tw51.biblioteca.io.menu;

import tw51.biblioteca.Lendable;
import tw51.biblioteca.Library;
import tw51.biblioteca.io.Input;
import tw51.biblioteca.io.Output;
import tw51.biblioteca.io.menu.home.MenuOptions;

import java.util.List;

import static tw51.biblioteca.ItemType.Book;

/**
* Prints the Items Of Type Book.
*/

public class PrintBooksOperation implements MenuOptions {

private Library library;
private Output writer;

@Override
public void execute(Library library, Input reader, Output writer) {
this.library = library;
this.writer = writer;
printBooks();
}

private void printBooks() {
writer.formattedHeadings();
writer.write("\n");
List<Lendable> items = library.listItems();
items.stream().filter(item -> item.isOfType(Book)).forEach(item -> {
writer.write("\n" + item.toFormattedString());
});
}
}


PrintBooksOperationTest.java

package tw51.biblioteca.io.menu;

import org.junit.Test;
import tw51.biblioteca.Book;
import tw51.biblioteca.Library;
import tw51.biblioteca.io.Input;
import tw51.biblioteca.io.Output;

import java.util.Arrays;
import java.util.LinkedList;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

/**
*
*/
public class PrintBooksOperationTest {

@Test
public void areTheBooksPrintedCorrectly() {
Input reader = mock(Input.class);
Output writer = mock(Output.class);
Book book = new Book("nin", "#123", "ghy", 2003);
Library library = new Library(new LinkedList<>(Arrays.asList(book)));
PrintBooksOperation print = new PrintBooksOperation();
print.execute(library, reader, writer);
verify(writer).write("");
}
}


Input and Output are interfaces that implement console read and write.

My Error Message:

Argument(s) are different! Wanted:
output.write(
""
);
-> at tw51.biblioteca.io.menu.PrintBooksOperationTest.areTheBooksPrintedCorrectly(PrintBooksOperationTest.java:28)
Actual invocation has different arguments:
output.write(
"
"
);


Why are the actual arguments empty? The Printoperation works when I run it. Is there something that I am doing wrong? Or is there another way to test the console??

Answer

When you call verify on the writer instance you're signalling that it should be called for the first time with the argument "".

From your implementation however you write to it several times

private void printBooks() {
        writer.formattedHeadings();
        writer.write("\n"); // <-- This is the first time
        List<Lendable> items = library.listItems();
        items.stream().filter(item -> item.isOfType(Book)).forEach(item -> {
            writer.write("\n" + item.toFormattedString());
        });
    }

Note that the first time you call write the argument is actually "\n" which is a newline, this does not match and empty string and the test fails. Either change the test to check for a "\n" or change the method to print what you expect.

Comments