使用Mockito

时间:2016-02-05 11:54:29

标签: unit-testing junit mockito

我似乎无法模仿Mockito上的虚空方法。它会在此处检测到未完成的存根错误。这是我的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);
}
}

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

1 个答案:

答案 0 :(得分:2)

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

你的问题不是模仿void方法,而是模仿static方法,而Mockito无法做到这一点。在幕后,Mockito正在创建一个覆盖你的模拟/间谍类(BibliotecaApp)以覆盖每个方法,但因为static方法不能以同样的方式被覆盖,Mockito可以& #39; t改变mainMenu的行为 - 甚至只是为了检测你在短戳中调用它,这就是为什么它会显示为&#34;未完成的短语&#34;。

static移除mainMenu修饰符,您将超越该障碍。

旁注:你也会窥探一堂课,但保留原作。这在Mockito中并不是一个好主意:间谍实际上创建了对象的副本,因此,如果您依赖适用于间谍的行为,您将拥有在间谍上调用测试方法。 (这是在测试中避免间谍的部分原因:使用间谍可能会模糊测试系统行为和测试Mockito行为之间的界限。)

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)