How Should I write JUnit test in the following case? - java

I am new in the Unit Testing.
I have a class Ckeckout which main function is to print the amount to be paid for books. The user types the titles of the books in the command line, and based on some calculations I have to output the final price.
Here is the Book class:
public class Book {
private String title;
private double price;
private int year;
public Book(String title, double price, int year) {
super();
this.title = title;
this.price = price;
this.year = year;
}
}
And here is the Checkout class:
public class Checkout {
private List<Book> books;
public Checkout(List<Book> books) {
super();
this.books = books;
}
//calculate the final price
private double getPrice(){
//return some double
}
}
What I want to test is just getPrice method. However, to do so, do I have to create list of Book objects in my CheckoutTest? Also, I will have to verify the final result with some very long number (like 62.01997301). Isn't it easier, to test the main() method, since in my Unit test, there won't be any need to create the Book objects (I will work only with Strings) and I can verify the output with shorter number (like 62.01)?

However, to do so, do I have to create list of Book objects in my CheckoutTest?:Generally and in any kind - yeah!
Also, I will have to verify the final result with some very long number (like 62.01997301): Naah, this depends on your targeting test/code quality! (for a "price" 2 digits should be sufficient (in any country!?))
Isn't it easier, to test the main() method, since in my Unit test, there won't be any need to create the Book objects (I will work only with Strings) and I can verify the output with shorter number (like 62.01)? Definitely! But with the current setup some (human) would have to check the console for "passing that test", for JUnit(and programmatically testing the value), you should/will need to make "getPrice() more visible" ... or in some way access its value.

Related

Is there a way for a combobox to get unique info from enum depending on user selection?

So I am doing some revision in preparation for a uni GUI exam.
My Enum has a list of >20 items that all have a unique name and cost.
This is my current enum
public enum List
{
Brush ("Brush", 2),
Clock ("Brush", 5);
private String name;
private int cost;
private List(String name, int cost)
{
this.name = name;
this.cost = cost;
}
}
I want the user to select an item option in which it references the enum and gets the specific name and cost so I can output it into cost calculations and print lines. How would I be able to do that? All I know is that it can use indexes to search for it but I'm not too sure.

How to print Array of Object in java

Assuming there is a Class called Product which has two product object called p1 and p2 which have the following fields:
P1--> int productId =123, String name ="iPhoneS8", int unitPrice
=1000, String datMfs ="12/18/2017". P2--> int productId =124, String name ="Samsung Galaxy S8", int unitPrice =1200, String datMfs
="05/22/2016".
The first question is
1), Write a java code for the product including getters and setters
methods, any three overloaded constructors including default. My
solution code is the following.
class Product {
Product() {//default Constractor
}
Product(int price) {//Overloaded Constractor1
}
Product(String name) {//Overloaded Constractor2
}
Product(String name, double pri) {//Overloaded Constractor3
}
Product(int name, double pri) {//Overloaded Constractor4
}
// The following is the product fields
private int productId;
private String name;
private int unitPrice;
private String dateMdft;
//The following is getters and setters
public int getproductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
public String getproductName() {
return name;
}
public void setProductname(String name) {
this.name = name;
}
public int getproductunitPrice() {
return unitPrice;
}
public void setUnitPrice(int unitPrice) {
this.unitPrice = unitPrice;
}
public int getUnitPrice() {
return unitPrice;
}
public void setDateMan(String dateMdft) {
this.dateMdft = dateMdft;
}
public String getDateManftd(String dateMdft) {
return dateMdft;
}
The second Question is
2), Write a method called printOutedDatedProduct(from the above) and
iterate through the object and print out the data for only the
outdated product to the screen in CSV format. the method should print
124, Samsung Galaxy S8,1200, 5/22/2016.
I am really Struggling to write the method and print out the outdated product so I really appreciate the community if anybody helps me and I am also really open to take any comments as far as the solution to the first question is concerned too. Great Thanks!
I would recommend to store date in LocalDate object. Why LocalDate? It is a well-written and tested class for date mainetenance.
How to instantiate and compare:
LocalDate d1 = LocalDate.of(2000, 06, 26);//YYYY-MM-DD
LocalDate d2 = LocalDate.now();
System.out.println(d1.compareTo(d2));//if d1 < d2, returns negative integer (difference between dates), otherwise positive integer.
What does d1.compareTo(d2)? It returns an integer representing the difference bwtween dates. It takes the first terms of dates that don't match and subtracts the second from the first. For example: 2019-03-14 compared to now (2019-03-29) will return 14-29 = -15.
You need to call compareTo(LocalDate) method for each LocalDate field of Product instance and compare with LocalDate.now();. When the numer is negative, print info about the product.
Java by default calls the toString method when you try to use an object as a String then what you need to do is to prepare the Product toString method first like this below:
public String toString(){
return productId+", "+name+", "+unitPrice+", "+dateMdft;
}
after that, the printing is going to be easy but you need to check for the date, manipulating a date as a String will cost you a lot. you can find java dates best practices presented in a good way here
after you learned how to use the Date class and how to check your date now you all you need to write the function that loops on the array you have and checks the date and print your data.
First, think about right datatypes for fields. You can use String for date filed, but how will you compare this dates? There is powerful JDK datetime API, let's use it. I'll recommend LocaDate, as you need only date part.
Second. Your constructors shouldn't be empty or useless. You could initialize object fields in constructors. For example:
Product(String name) {
this(name, 0);
}
Product(String name, int unitPrice) {
this(name, unitPrice, LocalDate.now());
}
Product(String name, int unitPrice, LocalDate dateMdft) {
this.name = name;
this.unitPrice = unitPrice;
this.dateMdft = dateMdft;
}
The next step is method for string representation of object. You could override toString or create another.
private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM/dd/YYYY");
#Override
public String toString() {
return productId + "," + name + "," + unitPrice + "," + dateTimeFormatter.format(dateMdft);
}
And the last, filter and print.
public static void main(String args[]) {
List<Product> products = new ArrayList<>();
products.add(new Product("1", 100, LocalDate.now().minusDays(1)));
products.add(new Product("2", 150, LocalDate.now().minusDays(2)));
products.add(new Product("3", 250, LocalDate.now()));
System.out.println("Via for loop:");
for (Product p: products) {
if (p.getDateMdft().isBefore(LocalDate.now())) {
System.out.println(p);
}
}
System.out.println("Via stream API:");
products
.stream()
.filter(p -> p.getDateMdft().isBefore(LocalDate.now()))
.forEach(System.out::println);
}

Constructor error- Cannot be applied to given types

I am writing a CSV parser, im almost done but i have an issuse with a return method. The code is almost the same as from this site, but I still get error.
private static Book createBook(String[] metadata) {
String name = metadata[0];
int price = Integer.parseInt(metadata[1]);
String author = metadata[2];
//Create and return book of this metadata
return new Book(name, price, author);
}
I get an error:
Error:(128, 16) java: constructor Book in class java.awt.print.Book cannot be applied to given types;
required: no arguments
found: java.lang.String,int,java.lang.String
reason: actual and formal argument lists differ in length
I am not sure what is causing this error, ive been dealing with this for many hours now. Thanks in advance.
Evidence:
The compilation error message talks about java.awt.print.Book
Your code is trying to create a Book like this: new Book(name, price, author)
Analysis: Those parameters make no sense for an java.awt.print.Book instance. The latter's javadoc says:
The Book class provides a representation of a document in which pages may have different page formats and page painters. This class uses the Pageable interface to interact with a PrinterJob.
So, it looks like you have accidentally imported java.awt.print.Book into your class when you really meant to import / use your own Book class. It probably was a result of an inappropriate "auto-correction" hint from your IDE.
Solution: Delete / replace the bogus import statement.
The concrete cause for the error is, that the Book class from the java.awt.print package does only have a zero-argument constructor and therefore can only be instantiated like this:
Book b = new Book();
And here comes something into play which can happen from time to time. The JDK API often feaatures classes which might sound like we could use them for our projects but often their name is a bit misleading or the desired functionality is not available.
If that's the case you should create/use your own class.
Assuming you already have a book class similar to this one:
public class Book
{
private final String name;
private final int price;
private final String author;
public Book( String name, int price, String author )
{
this.name = name;
this.price = price;
this.author = author;
}
// Getter....
}
You have to import the correct one for your project.
You can do so by adding a correct import statement:
import all.my.packages.Book
Another issue you may run into is if you want to use your own version of Book but also the one from the java.awt.print package. Now we run into a name clash and you have to specify each object when used:
public static void main( String[] args )
{
String author = "SomeAuthor";
String name = "SomeBook";
int price = 30;
java.awt.print.Book awtBook = new java.awt.print.Book();
playground.test.main.Book myBook = new playground.test.main.Book( name, price, author );
}
But that's something you want to avoid most of the time.

How do I add an item from a class to an ArrayList?

I know the question seems weird, but I'll try to explain it the best that I can. I am doing an Amusement Park Project where you have methods for the tickets, merchandise, etc. I made a Ticket class with the methods, but now I'm in the AmusementPark class trying to create a method of taking the date from that class and putting it into a new ArrayList. Maybe my code will help explain it.
First, here is my Ticket class......
import java.text.DecimalFormat;
public class Ticket {
private long number;
private String category;
private String holder;
private String date;
private double price;
private boolean purchased;
Ticket(long num, String cat, String h, String dt, double pr, boolean pch){
this.number= num;
this.category= cat;
this.holder= h;
this.date= dt;
this.price= pr;
this.purchased= pch;
}
long getNumber(){
return number;
}
String getCategory(){
return category;
}
String getHolder(){
return holder;
}
String getDate(){
return date;
}
boolean getPurchased(){
return purchased;
}
double getPrice(){
return price;
}
void setPrice(double pr){
price= pr;
}
void setChangePurchased(boolean newStatus){
purchased= newStatus;
}
#Override
public String toString(){
DecimalFormat dm= new DecimalFormat("#.##");
String disp;
disp = "Number: " + getNumber() + "\nCategory: " + getCategory() + "\nTicket Holder Name: " + getHolder() + "\nDate: " + getDate()
+ "\nPrice: " + dm.format(getPrice()) + "\nPuchased Completed?: " + purchased;
return disp;
}
}
Here is some of the Pseudo Code explaining what I am trying to do with the next class I'm about to post.
Create an ArrayList from the Ticket class.
//The ticket class has the following constructors....
// (Ticket number of type long, category of type String, Ticket holder of type String, Date of admission, purchase price of type double, variable named "purchased" whether the ticket has been paid for of type boolean)
//One of the variables of type class is tickets in which the ticket class is made into an ArrayList.
//The next task is to get tickets for dates where they are available, which is done by searching tickets where the purchase is not completed.
Create a public ArrayList<Date> method called getTicketDates(){
Create a variable called theDateArray which is a new ArrayList<Date>;
For(starting at the first position of the list, go through the the entire list incrementing by one){
if (boolean purchased of the Ticket ArrayList is false)**{
Add the date of the object from the Ticket ArrayList to theDateArray ArrayList.}** //This stores the dates of all tickets not yet purchased into the new ArrayList.
}
Return theDateArray;
}
//The next task is to search through theDateArray for only select dates and post the available tickets for that date as an integer.
Create a method which displays the number of tickets for a specified date by going through theDateArray (Date date) {
For(starting at the first position of theDateArray, go through the entire list and look for tickets that have a particular date){
if (the date== entered date){
Include the ticket as one of the tickets available for that date.
}
}
Return the total number of tickets available for that date as a type integer.
}
Okay, now here is my AmusementPark class. Note It is not finished. I'm just trying to get this one part done....
import java.util.ArrayList;
import java.util.Date;
public class AmusementPark {
private ArrayList<Ticket> tickets;
private ArrayList<Merchandise> merchandise;
private String name;
AmusementPark(String name){
this.name=name;
this.tickets = new ArrayList<Ticket>();
this.merchandise= new ArrayList<Merchandise>();
}
String getName(){
return name;
}
public ArrayList<String> getTicketDates(){
ArrayList<String> theDateArray= new ArrayList<>();
int i;
String date = Ticket.getDate(); //This is not working. See Reason Below.
for (i=0; i<tickets.size(); i++){
if(tickets.get(i).getPurchased()== false){
theDateArray.add(date);
}
}return theDateArray;
}
}
Okay, so now what happens when I try to call the method of getDate() from the Ticket class, it's not allowing me to use it for the reason that I cannot make a static reference to a non-static method. However, when I try to make the method static, it messes up the other class by saying I cannot make a static reference to a non-static field.
An ArrayList of the Ticket class has already been made. I need it to scroll through that list, get the ones where the boolean is false, and add the date to the next ArrayList.
Does this at all make sense?
Any ideas that would be better?
Let's take your method.
public ArrayList<String> getTicketDates(){
ArrayList<String> theDateArray= new ArrayList<>();
int i;
String date = Ticket.getDate(); //This is not working. See Reason Below.
for (i=0; i<tickets.size(); i++){
if(tickets.get(i).getPurchased()== false){
theDateArray.add(date);
}
}
return theDateArray;
}
Notice the problem on the Ticket.getDate() that you try to do whithout an instance, so a static call. But what you explain, you want the date for the Ticket of the list tickets. Good, you are iterating it after but are pushing this strange value date coming from a "static method".
You problem is that the instance holding the date you want is in the list. You are using it to see if it is purchased or not. So call the method on those instance to get the value :
for (i=0; i<tickets.size(); i++){
if(tickets.get(i).getPurchased()== false){
theDateArray.add(tickets.get(i).getDate());
}
}
But better :
Ticket ticket;
for (i=0; i<tickets.size(); i++){
ticket = tickets.get(i);
if(ticket.getPurchased()== false){
theDateArray.add(ticket.getDate());
}
}
If I understand it correctly what is required here is to extract dates for not purchased tickets into separate dates array. And you already got it correctly in your pseudocode, you just need to follow it more strictly during implementation:
public ArrayList<String> getTicketDates() {
ArrayList<String> theDateArray = new ArrayList<>();
// iterate over all tickets
for ( Ticket ticket : tickets ) {
// if ticket not purchased
if ( ! ticket.getPurchased() ) {
// add ticket's date into array
theDateArray.add( ticket.getDate() );
}
}
return theDateArray;
}
DON'T MAKE STATIC REFERENCE !Instead of writing a what's code answer let's focus on the workaround of problem.
Whenver you will set values to instance variables of TICKET Class it will refer to a particular object (new ticket()) to access its values if you make variables of class staticValues will be stored when class is loaded and not when object is created but arraylist items need to have
Object of ticket Class.
A simple approach should be
ASSIGN THE VALUES TO VARIABLES WHEN EVER YOU MAKE AN OBJECT OF TICKET CLASS BY BY PASSING VALUES IN ITS CONSTRUCTOR AND THEN
ADD THOSE OBJECTS TO ARRAYLISTITEMS
ticket class
public class Ticket {
private long number;
private String category;
private String holder;
private String date;
private double price;
private boolean purchased;
Ticket(long num, String cat, String h, String dt, double pr, boolean pch){
this.number= num;
this.category= cat;
this.holder= h;
this.date= dt;
this.price= pr;
this.purchased= pch;
}
make a new object and pass values
Ticket t1=new Ticket(3,"yourstring","yourstring",yourDouble,true/false);
add items in arrayliSt:
List<Tickets> tList=new ArrayList();
tList.add(t1);
tList.add(t2);
//and so on
now retrive values from arralylist
Ticket t=tlist.get(0);
t.cat;
t.whatevrbe thevalue be

How to store names in a database in java

Hi this is my first time using this because I am confused as to how I should go about this problem.
I have a spreadsheet which has multiple columns such as "house owner names", "Address", "price" etc. All of the columns have 12 values in them relating to 12 individuals each with their address and other such details regarding their property.
I need to create a program where if I enter a certain price range, the program sorts through the spreadsheet and only displays the results that fall within the price range that the user enters.
I first thought of using multiple one-dimensional arrays in parallel, but I am not sure if this is the correct way to do such a thing, also I do not know if it is possible to to search through arrays for specific ranges and then have it display to the console.
In this instance I would say your spreadsheet is acting as your database.
Rather than arrays, I would read the spread sheet into instances (objects) of a class, such that each class represents a row in your spreadsheet, and then put these instances into an ArrayList
You should then be able to "search" the ArrayList.
The object oriented way to handle this is to create a Java object with the 12 column names. Since you only gave us 3 column names, I created this Java objecvt with the 3 names.
public class HomeOwner {
private final String name;
private final String address;
private final double price;
public HomeOwner(String name, String address, double price) {
this.name = name;
this.address = address;
this.price = price;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
public double getPrice() {
return price;
}
}
You can now create a List of HomeOwner instances, and search the List by price or any of the other column names.

Categories

Resources