我有一个项目是一个硬件商店,包含保存,搜索和编辑数据的方法。数据是存储在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());
}
}
}
}
答案 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));
}