使用Mockito测试if方法的调用



我有一个菜单,根据给它的选择调用不同的操作。我想使用mockit来查看是否调用了正确的方法。这是我目前为止的实现…

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());
        });
    }
}

My Test:

    @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);
    }
}

My Error Message:

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.

我做错了什么?我怎么纠正这个??

您正在为PrintBooksOperation类(称为print)创建模拟,但是模拟根本没有发送到正在测试的类。因此,mockit会抛出异常,因为在mock上从未调用过execute函数。

我建议修改你的Menu类,这样你就可以注入
  • printItemsOfTypeBook
  • printItemsOfTypeMovie
  • loginAccount

而不是在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);

验证现在应该可以正常工作。

如果你对你的单元使用依赖注入,它基本上会使单元测试更容易。

相关内容

  • 没有找到相关文章

最新更新