如何使用junit为java程序设置基本测试方法?

时间:2018-03-30 21:10:33

标签: java eclipse junit

我有一个项目是一个硬件商店,包含保存,搜索和编辑数据的方法。数据是存储在txt数据库中的项目。我必须创建一个JUNIT测试用例来测试硬件商店类的方法。总共有三个类:hardwarestore,mainapp和item。但唯一需要测试的是hardwarestore。唯一不需要测试的方法是readDatabase()和writeDatabase()。

对于我的JUNIT类,我有hardwarestoretest,我将使用hardwarestore类的测试方法实现。我还有一个testrunner类,它在hardwarestoretest中运行测试方法。测试方法将由断言测试组成 Assertions

我对JUNIT测试相当新,需要一些帮助才能开始。我编写了部分测试类但是在运行时失败了。我得到的输出表明,即使我尝试为addNewItem实现测试方法,也没有可运行的测试。

这是我在hardwarestore包中的hardwarestore的代码

Item.java

package hardwarestore;

/**
 * This class is a very simple representation of a hardware item. There are only getter
 * methods and no setter methods and as a result an item cannot be mutated once
 * initialized. An item object can also call the two override methods
 * <CODE>toString()</CODE> and <CODE>equals()</CODE>
 *
 * @author Junye Wen
 */
public class Item {

    private final String idNumber;
    private final String name;
    private final String category;
    private int quantity;
    private final float price;

    /**
     * This constructor initializes the item object. The constructor provides no
     * user input validation. That should be handled by the class that creates a
     * item object.
     *
     * @param idNumber a <b><CODE>String</CODE></b> that represents the ID
     *                 random string of length 5 – can contain letters and numbers
     *
     * @param name a <b><CODE>String</CODE></b> that represents the name.
     *
     * @param category a <b><CODE>String</CODE></b> that represents the category.
     *                 Door&Window, Cabinet& Furniture, Fasteners, Structural, Other.
     *
     * @param quantity a <b><CODE>int</CODE></b> that represents the quantity
     *
     * @param price an <b><CODE>float</CODE></b> that represents the price
     *
     */
    public Item(String idNumber, String name, String category, int quantity, float price) {
        this.idNumber = idNumber;
        this.name = name;
        this.category = category;
        this.quantity = quantity;
        this.price = price;
    }

    /**
     * This method returns the item's tracking number.
     *
     * @return a <b><CODE>String</CODE></b> that is the ID number of the item.
     */
    public String getIdNumber() {
        return idNumber;
    }

    /**
     * This method returns the item's name.
     *
     * @return a <b><CODE>String</CODE></b> that is the item's name.
     */
    public String getName() {
        return name;
    }

    /**
     * This method returns the item's category.
     *
     * @return a <b><CODE>String</CODE></b> that is the item's category.
     */
    public String getCategory() {
        return category;
    }


    /**
     * This method returns the item's quantity.
     *
     * @return an <b><CODE>int</CODE></b> that is the item's weight
     */
    public int getQuantity() {
        return quantity;
    }

    /**
     * This method set the item's quantity.
     *
     *  @param quantity a <b><CODE>int</CODE></b> that represents the quantity
     */
    public void setQuantity(int quantity) {
        this.quantity= quantity;
    }

    /**
     * This method returns the item's price.
     *
     * @return a <b><CODE>float</CODE></b> that is the item's price
     */
    public float getPrice() {
        return price;
    }

    /**
     * This method returns the item's fields as a string representation.
     *
     * @return a <b><CODE>String</CODE></b> that lists the fields of the item
     * object delineated by a space and in the same order as the constructor
     */
    @Override
    public String toString() {
        return idNumber + "~" + name + "~" + category + "~" + quantity + "~"
                + String.format("%.2f", price) + "\n";
    }

    /**
     * This method provides a way to compare two item objects.
     *
     * @param c a <b><CODE>Item</CODE></b> object that is used to compare to
     * <b><CODE>this</CODE></b> item. Two orders are equal if their ID is the
     * same.
     * @return the <CODE>boolean</CODE> value of the comparison.
     */
    public boolean equals(Item c) {
        return c.getIdNumber().equals(this.idNumber);
    }

}

HardwareStore.java

package hardwarestore;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Scanner;

/**
 * This class is used to represent a database interface for a list of
 * <CODE>item</CODE>'s. It using a plain-text file "database.txt" to store and
 * write item objects in readable text form. It contains an
 * <CODE>ArrayList</CODE> called <CODE>itemList</CODE> to store the database in
 * a runtime friendly data structure. The <CODE>itemList</CODE> is written to
 * "database.txt" at the end of the <CODE>HardwareStore</CODE> object's life by
 * calling <CODE>writeDatabase()</CODE>. This class also provides methods for
 * adding, removing, and searching for items in the list.
 *
 * @author Junye Wen
 */
public class HardwareStore {

    private ArrayList<Item> itemList;

    private static final String DATA_FILE_NAME = "database.txt";

    /**
     * This constructor creates an empty ArrayList and then calls the 
     * <CODE>readDatabase()</CODE> method to populate items previously stored. 
     *
     * @throws IOException
     */
    public HardwareStore() throws IOException {
        itemList = new ArrayList<>();
        readDatabase();
    }

    /**
     * Method getAllItemsFormatted returns the current list of items in the Arraylist in
     * no particular order.
     * 
     * @return a formatted String representation of all the items in itemList.
     */
    public String getAllItemsFormatted() {
        return getFormattedItemList(itemList);
    }

    /**
     * Private method getFormattedPackageList used as an auxiliary method to return a given ArrayList
     * of items in a formatted manner.
     *
     * @param items the item list to be displayed.
     * @return a formatted String representation of all the items in the list give as a parameter.
     */
    private String getFormattedItemList(ArrayList<Item> items) {

        String text = " ------------------------------------------------------------------------------------\n" +
                String.format("| %-10s| %-25s| %-20s| %-10s| %-10s|%n", "ID Number", "Name", "Category", "Quantity", "Price") +
                      " ------------------------------------------------------------------------------------\n";

        for (int i = 0; i < items.size(); i++) {
            text += String.format("| %-10s| %-25s| %-20s| %-10s| %-10s|%n",
                    items.get(i).getIdNumber(),
                    items.get(i).getName(),
                    items.get(i).getCategory(),
                    Integer.toString(items.get(i).getQuantity()),
                    String.format("%.2f", items.get(i).getPrice()));
        }
        text += " ------------------------------------------------------------------------------------\n";

        return text;
    }


    /**
     * This method is used to add a item to the itemList ArrayList.
     *
     * @param idNumber a <CODE>String</CODE> representing the ID number of item
     * @param name a <CODE>String</CODE> representing the name of item
     * @param category a <CODE>String</CODE> representing the category of item
     * @param quantiy an <CODE>int</CODE> representing the quantiy of item
     * @param price a <CODE>float</CODE> representing the price of item
     */
    public void addNewItem(String idNumber, String name, String category, int quantiy, float price) {
        //If passed all the checks, add the item to the list
        itemList.add(new Item(idNumber, name, category, quantiy, price));
        System.out.println("Item has been added.\n");
    }


    /**
     * Add a certain quantity of the given item index.
     * Preconditions: 1. Item exists.
     * @param itemIndex the index of the item in the itemList
     * @param quantity  the quantity to remove
     */
    public void addQuantity(int itemIndex, int quantity) {
        Item temp = getItem(itemIndex);
        temp.setQuantity(temp.getQuantity() + quantity);
        System.out.println("Quantity updated.\n");
    }


    /**
     * Removes a certain quantity of the given item index. 
     * Preconditions: 1. Item exists. 2. Quantity to remove smaller than current quantity.
     * @param itemIndex the index of the item in the itemList
     * @param quantity  the quantity to remove
     */
    public void removeQuantity(int itemIndex, int quantity) {
        Item temp = getItem(itemIndex);
        temp.setQuantity(temp.getQuantity() - quantity);
        System.out.println("Quantity updated.\n");
    }

    /**
     * Returns all the items that (partially) match the given name.
     * @param name the name to match.
     * @return a string containing a table of the matching items.
     */
    public String getMatchingItemsByName(String name) {
        ArrayList<Item> temp = new ArrayList<Item>();
        for (Item tempItem : itemList) {
            if (tempItem.getName().toLowerCase().contains(name.toLowerCase())) {
                temp.add(tempItem);
            }
        }

        if (temp.size() == 0) {
            return null;
        } else {
            return getFormattedItemList(temp);
        }
    }

    /**
     * Returns all the items with current quantity lower than (or equal) the
     * given threshold.
     * @param quantity the quantity threshold.
     * @return a string containing a table of the matching items.
     */
    public String getMatchingItemsByQuantity(int quantity) {
        ArrayList<Item> temp = new ArrayList<Item>();
        for (Item tempItem : itemList) {
            if (tempItem.getQuantity() <= quantity) {
                temp.add(tempItem);
            }
        }

        if (temp.isEmpty()) {
            return null;
        } else {
            return getFormattedItemList(temp);
        }
    }

    /**
     * This method can be used to find a item in the Arraylist of items.
     *
     * @param idNumber a <CODE>String</CODE> that represents the ID number of
     * the item that to be searched for.
     * @return the <CODE>int</CODE> index of the items in the Arraylist of
     * items, or -1 if the search failed.
     */
    public int findItem(String idNumber) {

        int index = -1;

        for (int i = 0; i < itemList.size(); i++) {
            String temp = itemList.get(i).getIdNumber();

            if (idNumber.equalsIgnoreCase(temp)) {
                index = i;
                break;
            }

        }

        return index;
    }

    /**
     * This method is used to retrieve the Item object from the
     * <CODE>itemList</CODE> at a given index.
     *
     * @param i the index of the desired <CODE>Item</CODE> object.
     * @return the <CODE>Item</CODE> object at the index or null if the index is
     * invalid.
     */
    public Item getItem(int i) {
        if (i < itemList.size() && i >= 0) {
            return itemList.get(i);
        } else {
            System.out.println("Invalid Index.\n");
            return null;
        }
    }

    /**
     * This method opens the database file and overwrites it with a
     * text representation of all the items in the <CODE>itemList</CODE>. This
     * should be the last method to be called before exiting the program.
     *
     * @throws IOException
     */
    public void writeDatabase() throws IOException {
        PrintWriter pw = new PrintWriter(DATA_FILE_NAME);

        for (Item c : itemList) {
            pw.print(c.toString());
        }

        pw.close();
    }

    /**
     * The method opens the database file and initializes the <CODE>itemList</CODE> 
     * with its contents. If no such file exists, then one is created. 
     * The contents of the file are "loaded" into the itemList ArrayList in no 
     * particular order. The file is then closed during the duration of the 
     * program until <CODE>writeDatabase()</CODE> is called.
     *
     * @throws IOException
     */
    public void readDatabase() throws IOException {

        File dataFile = new File(DATA_FILE_NAME);

        // If data file does not exist, create it.
        if (!dataFile.exists()) {
            System.out.println("database.txt does not exist, creating one now . . .");
            //if the file doesn't exists, create it
            PrintWriter pw = new PrintWriter(DATA_FILE_NAME);
            //close newly created file so we can reopen it
            pw.close();

            return; // No need to try to read anything from an empty file, so return.
        }
        Scanner itemScanner = new Scanner(new FileReader(dataFile));

        //Initialize the Array List with items from database.txt
        while (itemScanner.hasNextLine()) {

            // split values using the space character as separator
            String[] temp = itemScanner.nextLine().split("~");

            itemList.add(new Item(temp[0], temp[1], temp[2],
                    Integer.parseInt(temp[3]), Float.parseFloat(temp[4])));
        }

        //item list is now in the ArrayList completely so we can close the file
        itemScanner.close();
    }

}

MainApp.java

package hardwarestore;

import java.io.IOException;
import java.util.Scanner;

/**
 * This is the main class of the Hardware Store database manager. It provides a
 * console for a user to use the 5 main commands.
 *
 * @author Junye Wen
 */
public class MainApp {

    // This object will allow us to interact with the methods of the class HardwareStore
    private final HardwareStore hardwareStore;
    private static final Scanner CONSOLE_INPUT = new Scanner(System.in); // Used to read from System's standard input

    /**
     * Default constructor. Initializes a new object of type HardwareStore
     *
     * @throws IOException
     */
    public MainApp() throws IOException {
        hardwareStore = new HardwareStore();
    }

    /**
     * Shows all items in the inventory.
     */
    public void showAllItems() {
        System.out.print(hardwareStore.getAllItemsFormatted());
    }

    /**
     * This method will add items quantity with given number. If the item does
     * not exist, it will call another method to add it.
     *
     */
    public void addItemQuantity() {

        System.out.println("Please input the ID of item");
        String idNumber = CONSOLE_INPUT.nextLine();

        if (!idNumber.matches("[A-Za-z0-9]{5}")) {
            System.out.println("Invalid ID Number: not proper format. "
                    + "ID Number must be 5 alphanumeric characters.\n");
            return;
        }

        int itemIndex = hardwareStore.findItem(idNumber);
        if (itemIndex != -1) { // If item exists in the database

            System.out.println("Item found in database. Please enter quantity to add.");
            int quantity = CONSOLE_INPUT.nextInt();
            if (quantity <= 0) {
                System.out.println("Invalid quantity. "
                        + "The addition amount must be larger than 0.\n");
                return;
            }
            hardwareStore.addQuantity(itemIndex, quantity);
        } else {
            //If it reaches here, the item does not exist. We need to add new one.
            System.out.println("Item with given number does not exist.\n");

            // Enter name
            System.out.println("\nPlease type the name of item.");
            String name = CONSOLE_INPUT.nextLine();

            // Entery category
            String category = null;
            System.out.println("\nPlease select the category of item.");
            System.out.println("1: Door&Window\n2: Cabinet&Furniture\n3: Fasteners\n4: Structural\n5: Other");
            int selection = CONSOLE_INPUT.nextInt();
            switch (selection) {
                case 1:
                    category = "Door&Window";
                    break;
                case 2:
                    category = "Cabinet&Furniture";
                    break;
                case 3:
                    category = "Fasteners";
                    break;
                case 4:
                    category = "Structural";
                    break;
                case 5:
                    category = "Other";
                    break;
                default:
                    System.out.println("Invalid category number.");
                    return;
            }

            // Entery quantity
            System.out.println("\nPlease type the quantity of the item.");
            int quantity = CONSOLE_INPUT.nextInt();
            if (quantity < 0) {
                System.out.println("Invalid price. "
                        + "The quantity cannot be smaller than 0.");
                return;
            }

            // Enter price
            System.out.println("\nPlease type the price of the item.");
            float price = CONSOLE_INPUT.nextFloat();
            if (price < 0) {
                System.out.println("Invalid price. "
                        + "The price cannot be smaller than 0.");
                return;
            }

            hardwareStore.addNewItem(idNumber, name, category, quantity, price);
        }

    }

    /**
     * This method will remove the given quantity of an item with given number.
     * If the item does not exist, it will show an appropriate message.
     */
    public void removeItemQuantity() {

        System.out.println("Please input the ID of item");
        String idNumber = CONSOLE_INPUT.nextLine();
        if (!idNumber.matches("[A-Za-z0-9]{5}")) {
            System.out.println("Invalid ID Number: not proper format. "
                    + "ID Number must be at least 5 alphanumeric characters.");
            return;
        }

        int itemIndex = hardwareStore.findItem(idNumber);
        int currentQuantity;
        if (itemIndex == -1) {
            System.out.println("Item does not exist.\n");
            return;
        } else {
            currentQuantity = hardwareStore.getItem(itemIndex).getQuantity();
            System.out.println("Current quantity: " + currentQuantity + "\n");
        }

        System.out.println("Please input the quantity to remove.");
        int quantity = CONSOLE_INPUT.nextInt();
        if (quantity > currentQuantity) {
            System.out.println("Invalid quantity. "
                    + "The removal amount must be smaller than current quantity.\n");
        } else {
            hardwareStore.removeQuantity(itemIndex, quantity);
        }
    }

    /**
     * This method can search item by a given name (part of name.
     * Case-insensitive.) Will display all items with the given name.
     */
    public void searchItemByName() {

        System.out.println("Please input the name of item.\n");
        String name = CONSOLE_INPUT.nextLine();

        String output = hardwareStore.getMatchingItemsByName(name);
        if (output == null) {
            System.out.println("Item not found.");
        } else {
            System.out.println(output);
        }
    }

    /**
     * This method can search item below a certain quantity. Will display all
     * items fits such condition.
     */
    public void searchItemByQuantity() {

        System.out.println("Please enter the quantity:\n");
        int quantity = CONSOLE_INPUT.nextInt();

        if (quantity < 0) {
            System.out.println("Quantity should be at least 0.\n");
        }

        String output = hardwareStore.getMatchingItemsByQuantity(quantity);
        if (output == null) {
            System.out.println("No items found below given quantity.");
        } else {
            System.out.println(output);
        }
    }

    public void saveDatabase() throws IOException {
        hardwareStore.writeDatabase();
    }

    /**
     * This method will begin the user interface console. Main uses a loop to
     * continue executing commands until the user types '6'.
     *
     * @param args this program expects no command line arguments
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {

        MainApp app = new MainApp();

        String welcomeMessage = "\nWelcome to the Hardware Store database. Choose one of the following functions:\n\n"
                + "\t1. Show all existing items in stock and their quantities.\n"
                + "\t2. Add a new quantity of a specific item to the stock.\n"
                + "\t3. Remove a certain quantity of a specific item type.\n"
                + "\t4. Search for an item (given its name or part of its name).\n"
                + "\t5. Show a list of all items below a certain quantity.\n"
                + "\t6. Exit program.\n";

        System.out.println(welcomeMessage);

        int selection = CONSOLE_INPUT.next().charAt(0);
        CONSOLE_INPUT.nextLine();

        while (selection != '6') {

            switch (selection) {
                case '1':
                    app.showAllItems();
                    break;
                case '2':
                    app.addItemQuantity();
                    break;
                case '3':
                    app.removeItemQuantity();
                    break;
                case '4':
                    app.searchItemByName();
                    break;
                case '5':
                    app.searchItemByQuantity();
                    break;
                case 'h':
                    System.out.println(welcomeMessage);
                    break;
                default:
                    System.out.println("That is not a recognized command. Please enter another command or 'h' to list the commands.");
                    break;

            }

            System.out.println("Please enter another command or 'h' to list the commands.\n");
            selection = CONSOLE_INPUT.next().charAt(0);

            CONSOLE_INPUT.nextLine();
        }

        CONSOLE_INPUT.close();


        System.out.print("Saving database...");
        app.saveDatabase();

        System.out.println("Done!");

    }
}

以下是测试包中的测试类

HardwareStoreTest.java

package test;

import static org.junit.Assert.assertNotNull;

import java.io.IOException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.jupiter.api.Test;
import hardwarestore.*;

public class HardwareStoreTest {

    public static HardwareStore hardwarestore = null;

    @BeforeClass
    public static void createEnvironment() throws IOException {
        hardwarestore = new HardwareStore();
    }

    @AfterClass 
    public static void clearEnvironment() {
        hardwarestore = null;
        System.out.println("Environment cleared");
    }

    @Test
    public static void testAddItem() {
        hardwarestore.addNewItem("123543","sink","other",23,24.95f);
        assertNotNull("Test Failed message", hardwarestore.getItem(0));
    }

}

TestRunner.java

package test;

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

class TestRunner {

public static void main(String[] args) {

    Result result = JUnitCore.runClasses(HardwareStoreTest.class);
    if(result.getFailures().size()==0) {
        System.out.println("All tests successfull!");
    }else {
        System.out.println("No. of failed test cases = "+ result.getFailures().size());
        for(Failure failure : result.getFailures()) {
            System.out.println(failure.toString());
        }
    }
}

}

1 个答案:

答案 0 :(得分:0)

在顶部更改导入,测试不应该是静态的。

import org.junit.Test

@Test
public void addNewItem(){
    hardwarestore.addNewItem("123RT", "sink", "kitchen", 34, 4.51f);
    assertNotNull("Test Failed Message", hardwarestore.getItem(0));

}