Java 测试是否使用Mockito调用了方法

Java 测试是否使用Mockito调用了方法,java,unit-testing,mocking,mockito,Java,Unit Testing,Mocking,Mockito,我有一个菜单,根据给它的选择调用不同的操作。我想使用mockito来查看是否调用了正确的方法。 这是我到目前为止的植入 Menu.java: “我的菜单”包含不同选项的选项和实例 printItemOfTypeBook是PrintBookOperation的一个实例 private void setMenuOptions() { char keyForPrintingBooks = '1'; char keyForPrintingMovies = '2';

我有一个菜单,根据给它的选择调用不同的操作。我想使用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());
        });
    }
}

我做错了什么??如何更正此问题???

您正在为PrintBooksOperation类(称为print)创建一个模拟,但该模拟根本不会发送到正在测试的类。因此,mockito抛出一个异常,因为从未对mock调用execute函数

我建议改变你的菜单类,这样你就可以

  • printItemsOfTypeBook
  • PrintItemSoftype电影
  • 逻辑计数
  • 退出
而不是在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);
验证现在应该可以正常工作了


基本上,如果您对单元使用依赖项注入,那么单元测试会变得容易得多。

您模拟的是
printbooks操作
,但是您根本没有使用它。最后,
验证
是否调用了
execute
方法,因此该方法无法工作(因为从未调用过)。你到底想做什么和测试?另外,请将代码缩减为a,这里有太多不相关的代码。也就是说,很明显,您没有对
print
执行任何操作,因此不会对其调用任何方法。@Oliver代码运行并正确打印。我的第一个菜单选项是printItemsOfTypeBook,它是PrintBookOperation类的一个实例。因此,当我通过“1”来应用选择时,逻辑操作系统。它应该调用execute,然后像您建议的那样使用调试器选项检查printI。它会被调用
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);