我有一个菜单,根据给出的选择调用不同的操作。我想使用mockito来查看是否调用了正确的方法。 这是我到目前为止的实施......
Menu.java:
我的菜单包含不同选项的选项和实例。
例如。 printItemOfTypeBook是PrintBookOperation的一个实例。
private void setMenuOptions() {
char keyForPrintingBooks = '1';
char keyForPrintingMovies = '2';
char keyForAccountLogin = '3';
char keyForExit = '4';
menuOptions.put(keyForPrintingBooks, printItemsOfTypeBook);
menuOptions.put(keyForPrintingMovies, printItemsOfTypeMovie);
homeMenuOptions.put(keyForAccountLogin, loginAccount);
homeMenuOptions.put(keyForExit, quit);
}
然后我将一个字符传递给apply choice方法,该方法找到适当的实例并在其上调用execute。
public void applyChoice(char choice) {
if ((!menuOptions.containsKey(choice)) && (!homeMenuOptions.containsKey(choice))) {
new WrongChoiceOperation();
}
if (menuOptions.containsKey(choice)) {
menuOptions.get(choice).execute(library, reader, writer);
}
if (homeMenuOptions.containsKey(choice)) {
homeMenuOptions.get(choice).execute(library, reader, writer);
}
}
}
我正在测试第一个打印书籍的选项。所以我模拟PrintBookOperation类并检查其中的execute方法是否被调用。
PrintBookOperation.java:
@Override
public void execute(Library library, Input reader, Output writer) {
this.library = library;
this.writer = writer;
printBooks();
}
private void printBooks() {
writer.formattedHeadings();
List<Lendable> items = library.listItems();
items.stream().filter(item -> item.isOfType(Book)).forEach(item -> {
writer.write("\n" + item.toFormattedString());
});
}
}
我的测试:
@Test
public void isThePrintOperationCalled() {
Input reader = new ConsoleInput();
Output writer = new ConsoleOutput();
PrintBooksOperation print = mock(PrintBooksOperation.class);
Book book = new Book("nin", "#123", "ghy", 2003);
Library library = new Library(new LinkedList<>(singletonList(book)));
Menu menu = new Menu(reader, writer, library);
menu.applyChoice('1');
verify(print).execute(library, reader, writer);
}
}
我的错误讯息:
Wanted but not invoked:
printBooksOperation.execute(
tw51.biblioteca.Library@39c0f4a,
Mock for Input, hashCode: 1471868639,
Mock for Output, hashCode: 876563773
);
-> at tw51.biblioteca.io.menu.home.MenuTest.isThePrintOperationCalled(MenuTest.java:30)
Actually, there were zero interactions with this mock.
我做错了什么?我该如何纠正这个?
答案 0 :(得分:2)
您正在为PrintBooksOperation类创建一个模拟(称为print),但模拟不会发送到正在测试的类。因此,mockito会抛出异常,因为从未在模拟上调用 execute 函数。
我建议更改您的Menu类,以便注入
而不是在Menu.java中分配新实例。你可以这样做:
public class Menu {
public Menu(Input reader,
Output writer,
Library library,
PrintBooksOperation printItemsOfTypeBook,
PrintMoviesOperation printItemsOfTypeMovie,
LoginAccountOperation loginAccount,
QuitOperation quit) {
this.reader = reader;
this.writer = writer;
this.library = library;
this.printItemsOfTypeBook = printItemsOfTypeBook;
this.printItemsOfTypeMovie = printItemsOfTypeMovie;
this.loginAccount = loginAccount;
this.quit = quit;
}
}
(注意我猜到了上面其他操作类的类名)。现在,在您的测试类中,您可以执行以下操作:
PrintBooksOperation print = mock(PrintBooksOperation.class);
Menu menu = new Menu(reader, writer, library, print, null, null, null);
menu.applyChoice('1');
verify(print).execute(library, reader, writer);
验证现在应该正常运行。
基本上,如果您为单位使用依赖注入,它会使单元测试变得更加容易。