使用Mockito模拟void方法

编程入门 行业动态 更新时间:2024-10-28 00:24:30
本文介绍了使用Mockito模拟void方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我似乎无法在Mockito上模拟void方法.它给出了未完成的存根检测到此处错误.这是我的课程文件.

I cannot seem to mock void methods on Mockito. It gives a unfinished stubbing detected here error. Here is my classfile.

package com.twu.biblioteca; import java.io.InputStream; import java.io.PrintStream; import java.util.InputMismatchException; import java.util.Scanner; public class BibliotecaApp { public static class IntegerAsker { private final Scanner scanner; private final PrintStream out; public IntegerAsker(InputStream in, PrintStream out) { scanner = new Scanner(in); this.out = out; } public int ask(String message) { out.print(message); return scanner.nextInt(); } } public static int numberOfBooks = 0; public static class book{ int serialNo; String name; String author; int publication; int checkoutstatus; book(){ serialNo = -1; name = null; author = null; publication = -1; checkoutstatus = -1; } book(int serialNo,String name, String author, int publication){ this.serialNo = serialNo; this.name = name; this.author = author; this.publication = publication; this.checkoutstatus=checkoutstatus = 1; } } public static int getBoundIntegerFromUser(IntegerAsker asker,String message,int lowerBound,int upperBound) { int input; try { input = asker.ask(message); while(input>upperBound || input<lowerBound) input = asker.ask("Select a valid option! "); return input; } catch(InputMismatchException exception) { System.out.print("You have selected an invalid option! "); } return -1; } public static book[] booksList = new book[20]; public static String welcome(){ IntegerAsker asker = new IntegerAsker(System.in,System.out); return "**** Welcome Customer! We are glad to have you at Biblioteca! ****"; } public static void addBooks(){ book newBook1 = new book(1,"Head First Java","Bert Bates",2014); booksList[1] = newBook1; numberOfBooks += 1; book newBook2 = new book(2,"1000 IT Quizzes","Dheeraj Malhotra",2009); booksList[2] = newBook2; numberOfBooks += 1; book newBook3 = new book(3,"100 Shell Programs in Unix","Shivani Jain",2009); booksList[3] = newBook3; numberOfBooks += 1; } public static void mainMenu(IntegerAsker asker){ System.out.println("1 " + "List Books"); System.out.println("2" + " Checkout a Book"); System.out.println("3 " + "Quit"); int n = getBoundIntegerFromUser(asker,"Enter your choice. ",1,3); mainMenuaction(n,asker); } public static void mainMenuaction(int n,IntegerAsker asker){ if(n==1){ showBooks(); mainMenu(asker); } else if(n==2){ checkout(asker); } else if(n==3){ return; } } public static void showBooks(){ for(int i=1;i<=numberOfBooks;i++){ if(booksList[i].checkoutstatus!=0) System.out.println(booksList[i].serialNo + ".\t" + booksList[i].name + "\t" + booksList[i].author + "\t" + booksList[i].publication); } } public static void checkout(IntegerAsker asker){ int Input = asker.ask("Enter the serial numebr of the book that you want to checkout"); if(booksList[Input]!=null){ if(booksList[Input].checkoutstatus!=0){ booksList[Input].checkoutstatus=0; System.out.println("Thank you! Enjoy the book"); } else{ System.out.println("That book is not available."); } } else{ System.out.println("That book is not available."); } mainMenu(asker); } public static void main(String[] args) { System.out.println(welcome()); addBooks(); IntegerAsker asker = new IntegerAsker(System.in,System.out); mainMenu(asker); } }

这是我的测试文件-

package com.twu.biblioteca; import org.mockito.Mockito; import org.mockito.Mockito.*; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.*; public class ExampleTest { BibliotecaApp test = Mockito.mock(BibliotecaApp.class); @Test public void welcometest() { assertEquals("**** Welcome Customer! We are glad to have you at Biblioteca! ****",test.welcome()); } @Test public void addBooksTest(){ test.addBooks(); assertEquals("Head First Java",test.booksList[1].name); assertEquals("Dheeraj Malhotra",test.booksList[2].author); assertEquals(2009,test.booksList[3].publication); } @Test public void getBoundIntegerFromUserTest(){ BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class); when(asker.ask("Enter your choice. ")).thenReturn(99); when(asker.ask("Select a valid option! ")).thenReturn(1); BibliotecaApp.getBoundIntegerFromUser(asker,"Enter your choice. ",1,2); verify(asker).ask("Select a valid option! "); } @Test public void mainMenuTest(){ BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class); when(asker.ask("Enter your choice. ")).thenReturn(3); test.mainMenu(asker); verify(test).mainMenuaction(1,asker); } @Test public void checkoutTest(){ BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class); BibliotecaApp test = new BibliotecaApp(); BibliotecaApp mock = spy(test); when(asker.ask("Enter the serial numebr of the book that you want to checkout")).thenReturn(2); Mockito.doNothing().when(mock).mainMenu(asker); test.addBooks(); test.checkout(asker); assertEquals(0,test.booksList[2].checkoutstatus); } }

有人可以指出我做错了吗?

Can someone point out what I am doing wrong please ?

推荐答案

/* system */ public static void mainMenu(IntegerAsker asker){ ... } /* test */ Mockito.doNothing().when(mock).mainMenu(asker);

您的问题不是关于模拟void方法,而是关于模拟static方法,而Mockito无法做到.在后台,Mockito正在创建模拟/监视类(BibliotecaApp)的覆盖以覆盖每个方法,但是由于static方法不能以相同的方式覆盖,因此Mockito不能更改mainMenu的行为-甚至只是为了检测到您在存根中调用了它,这就是为什么它显示为未完成的存根"的原因.

Your problem isn't about mocking void methods, it's about mocking static methods, which Mockito can't do. Behind the scenes, Mockito is creating an override of your mocked/spied class (BibliotecaApp) to override each of the methods, but because static methods can't be overridden the same way, Mockito can't change mainMenu's behavior—even just to detect that you called it in the stubbing, which is why this shows up as "unfinished stubbing".

从mainMenu删除static修饰符,您将克服障碍.

Remove the static modifier from mainMenu and you'll be over that hurdle.

旁注:您也可以监视一堂课,但要保留原始内容.在Mockito中这不是一个好主意:间谍实际上会创建对象的副本,因此,如果您依赖于适用于间谍的行为,则必须调用测试方法在间谍上. (这是避免在测试中使用间谍程序的部分原因:使用间谍程序会模糊测试系统行为和测试Mockito行为之间的界线.)

Side note: You also spy on a class but keep the original around. This isn't a good idea in Mockito: A spy actually creates a copy of the object, so if you're relying on behavior that applies to the spy, you'll have to call the test methods on the spy. (This is part of the reason to avoid spies in your tests: using spies can blur the line between testing your system's behavior and testing Mockito's behavior.)

BibliotecaApp test = new BibliotecaApp(); BibliotecaApp mock = spy(test); when(asker.ask("...")).thenReturn(2); Mockito.doNothing().when(mock).mainMenu(asker); test.addBooks(); // should be: mock.addBooks() test.checkout(asker); // should be: mock.checkout(asker)

更多推荐

使用Mockito模拟void方法

本文发布于:2023-10-31 07:06:12,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1545378.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:方法   Mockito   void

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!