0

I wrote a small project named Sales Taxes on Intellij IDEA. To run the program, I included a main method. Now I need to write JUnit tests for the project. I do not have much experience about writing test classes. How can I turn my main method to Junit test class?

Here is the project that I constructed:

Basic sales tax is applicable at a rate of 10% on all goods, except books, food, and medical products that are exempt. Import duty is an additional sales tax applicable on all imported goods at a rate of 5%, with no exemptions. When I purchase items I receive a receipt which lists the name of all the items and their price (including tax), finishing with the total cost of the items, and the total amounts of sales taxes paid. The rounding rules for sales tax are that for a tax rate of n%, a shelf price of p contains (np/100 rounded up to the nearest 0.05) amount of sales tax. Write an application that prints out the receipt details for these shopping baskets...

Product.java

/*
Definition of Product.java class
Fundamental object for the project. 
It keeps all features of the product.
At description of the product, description of the input line for output line.
typeOfProduct: 0:other 1:food 2:book 3: medical products

*/

public class Product{

    private int typeOfProduct=0;
    private boolean imported=false;
    private double price=0;
    private double priceWithTaxes=0;
    private double taxes=0;
    private int quantity=0;
    private String description="";


    public Product(int quantity, int typeOfProduct, boolean imported, double price, String description)
    {
        this.quantity=quantity;
        this.typeOfProduct = typeOfProduct;
        this.imported = imported;
        this.price = price;
        this.description = description;

    }

    public void setTypeOfProduct(int typeOfProduct)
    {
        this.typeOfProduct = typeOfProduct;
    }

    public int getTypeOfProduct()
    {
        return typeOfProduct;
    }

    public void setImported(boolean imported)
    {
        this.imported = imported;
    }

    public boolean getImported()
    {
        return imported;
    }

    public void setPrice(double price)
    {
        this.price = price;
    }

    public double getPrice()
    {
        return price;
    }

    public void setTaxes(double taxes)
    {
        this.taxes = taxes;
    }

    public double getTaxes()
    {
        return taxes;
    }

    public void setPriceWithTaxes(double priceWithTaxes)
    {
        this.priceWithTaxes = priceWithTaxes;
    }

    public double getPriceWithTaxes()
    {
        return priceWithTaxes;
    }

    public void setQuantity(int quantity)
    {
        this.quantity = quantity;
    }

    public int getQuantity()
    {
        return quantity;
    }

    public void setDescription(String description)
    {
        this.description = description;
    }

    public String getDescription()
    {
        return description;
    }
}

TaxCalculator.java

/*
Definition of TaxCalculator.java class
At constructor a Product object is taken.
taxCalculate method; adds necessary taxes to price of product.
Tax rules: 
    1. if the product is imported, tax %5 of price
    2. if the product is not food, book or medical goods, tax %10 of  price
typeOfProduct: 0:food 1:book 2: medical products 3:other
*/
public class TaxCalculator {

private Product product=null;

    public TaxCalculator(Product product)
    {
        this.product=product;
    }

    public void taxCalculate()
    {
        double price=product.getPrice();
        double tax=0;

        //check impoted or not
        if(product.getImported())
        {
            tax+= price*5/100;

        }

        //check type of product
        if(product.getTypeOfProduct()==3)
        {
            tax+= price/10;
        }

        product.setTaxes(Util.roundDouble(tax));
        product.setPriceWithTaxes(Util.roundDouble(tax)+price);
    }
}

Util.java

import java.text.DecimalFormat;
/*
Definition of Util.java class
It rounds and formats the price and taxes.
Round rules for sales taxes: rounded up to the nearest 0.05
Format: 0.00
*/

public class Util {

    public static String round(double value)
    {
        double rounded = (double) Math.round(value * 100)/ 100;

        DecimalFormat df=new DecimalFormat("0.00");
        rounded = Double.valueOf(df.format(rounded));

        return df.format(rounded).toString();
    }

    public static double roundDouble(double value)
    {
        double rounded = (double) Math.round(value * 20)/ 20;

        if(rounded<value)
        {
            rounded = (double) Math.round((value+0.05) * 20)/ 20;
        }

        return rounded;
    }

    public static String roundTax(double value)
    {
        double rounded = (double) Math.round(value * 20)/ 20;

        if(rounded<value)
        {
            rounded = (double) Math.round((value+0.05) * 20)/ 20;
        }

        DecimalFormat df=new DecimalFormat("0.00");
        rounded = Double.valueOf(df.format(rounded));

        return df.format(rounded).toString();
    }
}

SalesManager.java

import java.util.ArrayList;
import java.util.StringTokenizer;
/*
Definition of SalesManager.java class
This class asks to taxes to TaxCalculator Class and creates Product    objects.
 */
public class SalesManager {

    private String [][] arTypeOfProduct = new String [][]{
            {"CHOCOLATE", "CHOCOLATES", "BREAD", "BREADS", "WATER", "COLA", "EGG", "EGGS"},
            {"BOOK", "BOOKS"},
            {"PILL", "PILLS", "SYRUP", "SYRUPS"}
    };
    /*
     * It takes all inputs as ArrayList, and returns output as ArrayList
     * Difference between output and input arrayLists are Total price and Sales Takes.
     */
    public ArrayList<String> inputs(ArrayList<String> items)
    {
        Product product=null;
        double salesTaxes=0;
        double total=0;

        TaxCalculator tax=null;

        ArrayList<String> output=new ArrayList<String>();

        for(int i=0; i<items.size(); i++)
        {
            product= parse(items.get(i));
            tax=new TaxCalculator(product);
            tax.taxCalculate();

            salesTaxes+=product.getTaxes();
            total+=product.getPriceWithTaxes();

            output.add(""+product.getDescription()+" "+Util.round(product.getPriceWithTaxes()));

        }

        output.add("Sales Taxes: "+Util.round(salesTaxes));

        output.add("Total: "+Util.round(total));

        return output;
    }

    /*
     * The method takes all line and create product object.
     * To create the object, it analyses all line.
     * "1 chocolate bar at 0.85"
     * First word is quantity
     * Last word is price
     * between those words, to analyse it checks all words
     */
    public Product parse(String line)
    {
        Product product=null;

        String productName="";
        int typeOfProduct=0;
        boolean imported=false;
        double price=0;
        int quantity=0;
        String description="";

        ArrayList<String> wordsOfInput = new ArrayList<String>();

        StringTokenizer st = new StringTokenizer(line, " ");

        String tmpWord="";
        while (st.hasMoreTokens())
        {
            tmpWord=st.nextToken();
            wordsOfInput.add(tmpWord);
        }

        quantity=Integer.parseInt(wordsOfInput.get(0));

        imported = searchImported(wordsOfInput);

        typeOfProduct = searchTypeOfProduct(wordsOfInput);

        price=Double.parseDouble(wordsOfInput.get(wordsOfInput.size()-1));

        description=wordsOfInput.get(0);
        for(int i=1; i<wordsOfInput.size()-2; i++)
        {
            description=description.concat(" ");
            description=description.concat(wordsOfInput.get(i));
        }
        description=description.concat(":");

        product=new Product(quantity, typeOfProduct, imported, price, description);

        return product;
    }

    /*
     * It checks all line to find "imported" word, and returns boolean as imported or not.
     */
    public boolean searchImported(ArrayList<String> wordsOfInput)
    {
        boolean result =false;
        for(int i=0; i<wordsOfInput.size(); i++)
        {
            if(wordsOfInput.get(i).equalsIgnoreCase("imported"))
            {
                return true;
            }
        }

        return result;
    }

    //typeOfProduct: 0:food 1:book 2: medical goods 3:other
    /*
     * It checks all 2D array to find the typeOf product
     * i=0 : Food
     * i=1 : Book 
     * i=2 : Medical goods
     */
    public int searchTypeOfProduct (ArrayList<String> line)
    {
        int result=3;
        for(int k=1; k<line.size()-2; k++)
        {
            for(int i=0; i<arTypeOfProduct.length; i++)
            {
                for(int j=0; j<arTypeOfProduct[i].length; j++)
                {
                    if(line.get(k).equalsIgnoreCase(arTypeOfProduct[i][j]))
                    {
                        return i;
                    }
                }
            }
        }
        return result;
    }
 }

SalesTaxes.java

import java.io.IOException;
import java.util.ArrayList;
public class SalesTaxes {

    public static void main(String args[]) throws IOException
    {
        ArrayList<String> input = new ArrayList<String>();
        ArrayList<String> output = new ArrayList<String>();

        SalesManager sal = new SalesManager();

            /*
             * First input set
             */
        System.out.println("First input Set");
        System.out.println();

        input = new ArrayList<String>();
        input.add("1 book at 12.49");
        input.add("1 music CD at 14.99");
        input.add("1 chocolate bar at 0.85");
        sal=new SalesManager();
        output= sal.inputs(input);

        for(int i=0; i<output.size(); i++)
        {
            System.out.println(output.get(i));
        }

            /*
             * Second input set
             */
        System.out.println();
        System.out.println("Second input Set");
        System.out.println();

        input = new ArrayList<String>();
        input.add("1 imported box of chocolates at 10.00");
        input.add("1 imported bottle of perfume at 47.50");
        sal=new SalesManager();
        output= sal.inputs(input);

        for(int i=0; i<output.size(); i++)
        {
            System.out.println(output.get(i));
        }
            /*
             * Third input set
             */
        System.out.println();
        System.out.println("Third input Set");
        System.out.println();

        input = new ArrayList<String>();
        input.add("1 imported bottle of perfume at 27.99");
        input.add("1 bottle of perfume at 18.99");
        input.add("1 packet of headache pills at 9.75");
        input.add("1 box of imported chocolates at 11.25");
        output= sal.inputs(input);

        for(int i=0; i<output.size(); i++)
        {
            System.out.println(output.get(i));
        }
    }
}
Holloway
  • 6,412
  • 1
  • 26
  • 33
oddly
  • 260
  • 3
  • 9
  • 22
  • Not. Writing unit tests is pretty basic. Just put down a few scenario's for each method, with input and expected output, run them and assert the output. You will need to learn to work with JUnit, though: http://www.vogella.com/tutorials/JUnit/article.html – Stultuske Mar 04 '15 at 10:12

2 Answers2

1

I think that you can start with searching about how to write unit tests, maybe than you will not have this kind of question. The main point there is to test some piece of functionality. For example, in your case you should test taxCalculate method and check if in your product the tax was set correctly, probably you will need a getter for a product in this case.

Also, check this: how to write a unit test.

Community
  • 1
  • 1
Rufi
  • 2,529
  • 1
  • 20
  • 41
0

A "unit test" is for one class.

So I wouldn't start with the main method: that wouldn't give you "unit tests". That would give you an "integration test" (testing a bunch of your classes all at once).

So, for unit tests, I would start by writing a UtilTest class to test just your Util class. That has public methods that can easily be given different inputs and the results asserted. e.g. what do you get back if you give roundTax zero, or 21.0, etc.?

David Lavender
  • 8,021
  • 3
  • 35
  • 55