Junit5 how to count employees in UnitTest - java

So I have 3 packages, Implementation, interfaces and test. I want to write the functionality into EmployeeImp so my unit test passes without error when I run it on TestEmployeeImp. However I'm not sure how getEmployeeCount is written as it fails in the unit test. I tried to solve it by creating the int count but it doesn't work. I know I need to use the array list to count the number of employees but I cannot come up with a solution and I can't find any samples of code that are like my unit test. If anyone can help it would be very appreciated.
//EmployeeImp
import java.util.ArrayList;
import java.util.List;
import interfaces.Employer;
import interfaces.Person;
public class EmployerImpl implements Employer {
private String name;
private List<Person> employees;
private int count;
public EmployerImpl(String n) {
//gets name
this.name = n;
//Array List
employees = new ArrayList<Person>();
// TODO Auto-generated constructor stub
}
#Override
public void hire(Person p, String title, double salary) {
p.setJob(null);
employees.add(p);
}
#Override
public List<Person> getEmployees() {
//Returns Employees in a List
return employees;
}
#Override
public int getEmployeeCount() {
return this.count;
//Returns employees size
}
#Override
public boolean fire(Person p) {
// TODO Auto-generated method stub
return false;
}
#Override
public String getName() {
//returns name
return name;
}
#Override
public boolean isEmployed(Person p) {
// TODO Auto-generated method stub
return false;
}
#Override
public Person getHighestPaid() {
// TODO Auto-generated method stub
return null;
}
#Override
public Person getLowestPaid() {
// TODO Auto-generated method stub
return null;
}
#Override
public double getStaffCost() {
// TODO Auto-generated method stub
return 0;
}
#Override
public int getCountOf(String title) {
// TODO Auto-generated method stub
return 0;
}
#Override
public List<Person> getAll(String title) {
// TODO Auto-generated method stub
return null;
}
}
//Employer.java
import java.util.List;
public interface Employer {
void hire(Person p, String title, double salary);
List<Person> getEmployees();
int getEmployeeCount();
boolean fire(Person p);
String getName();
boolean isEmployed(Person p);
Person getHighestPaid();
Person getLowestPaid();
double getStaffCost();
int getCountOf(String title);
List<Person> getAll(String title);
}
//TestEmployeeImp
import static org.junit.jupiter.api.Assertions.*;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import implementation.EmployerImpl;
import implementation.PersonImpl;
import interfaces.Employer;
import interfaces.Person;
class TestEmployerImpl {
private Employer e;
private Person highest;
private Person lowest;
#BeforeEach
void setUp() throws Exception {
e = new EmployerImpl("NCCO");
lowest = new PersonImpl("John", 18);
e.hire(lowest, "Lab Assistant", 20000);
highest = new PersonImpl("Anu", 50);
e.hire(highest, "Best Teacher", 80000);
e.hire(new PersonImpl("Damien", 18), "Teacher", 41000);
e.hire(new PersonImpl("Malachy", 45), "Teacher", 50000);
}
#Test
void testGetEmployees() {
List<Person> l = e.getEmployees();
assertNotNull(l);
assertEquals(4, l.size());
}
#Test
void testGetEmployeeCount() {
assertEquals(4, e.getEmployeeCount());
Person p = new PersonImpl("Paul H", 50);
e.hire(p, "teacher", 1000);
assertEquals(5, e.getEmployeeCount());
e.fire(p);
assertEquals(4, e.getEmployeeCount());
}
#Test
void testFire() {
Person p = new PersonImpl("Damien", 18);
boolean f= e.fire(p);
assertTrue(f);
assertEquals(3, e.getEmployeeCount());
p = new PersonImpl("Danika", 23);
f = e.fire(p);
assertFalse(f);
}
#Test
void testGetName() {
assertEquals("NCCO", e.getName());
}
#Test
void testIsEmployed() {
Person p = new PersonImpl("Damien", 18);
assertTrue(e.isEmployed(p));
p = new PersonImpl("Danika", 23);
assertFalse(e.isEmployed(p));
}
#Test
public void testGetHighestPaid() {
assertEquals(highest, e.getHighestPaid());
}
#Test
void getLowestPaid() {
assertEquals(lowest, e.getLowestPaid());
}
#Test
void getStaffCost() {
assertEquals(191000, e.getStaffCost());
}
#Test
void testGetCountOf() {
assertEquals(2, e.getCountOf("Teacher"));
assertEquals(0, e.getCountOf("Awesome Teacher"));
}
#Test
void testGetAll(){
assertEquals(2, e.getAll("Teacher").size());
assertNotNull(e.getAll("Dean"));
assertTrue(e.getAll("Dean").isEmpty());
}
}

I can't see any code which initialize or increment int count variable. But as you said, you don't need count variable and just use size() method in employees List
#Override
public int getEmployeeCount() {
return this.employees.size();
}

In #BeforeEach you're test by creating 4 employees.
Your hire method does 'employees.add(p);' , so it expands your list.
Your fire method does not do anything, just returning false.
Yet you expect in test testFire and testGetEmployeeCount that the number of employees has decreased. That does not happen and will fail.
You need the following fix:
IMPORTANT - Implement an equals and hash code on your PersonImpl class (so you can compare equal objects content instead of object-hash value). You can use guava or apache commmons or lombok or any other way to do that.
Then implement in 'fire' method:
#Override
public boolean fire(Person p) {
return employees.remove(p);
}
In this case I assume you will implement limitations in the 'hire' method on your class to have duplicate employees, so you need only to remove it once. If employees can be duplicate, then do to remove the employee including duplicates:
return employees.removeAll(Collections.singletonList(p));

Related

update object in hashmap by java 8 lambda

I created an item named player as follows:
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
public class player implements Comparable <player> {
int PlayerId ;
String name ;
double salary;
public player(int PlayerId) {
this.PlayerId = PlayerId;
}
public void setPlayerId(int PlayerId) {
this.PlayerId = PlayerId;
}
public void setName(String name) {
this.name = name;
}
public void setSalary(double salary) {
this.salary = salary;
}
public int getID() {
return PlayerId;
}
public String getName() {
return name;
}
public double getSalary() {
return salary;
}
#Override
public int hashCode() {
int key = 2;
return key=2*key+PlayerId;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final player other = (player) obj;
if (this.PlayerId != other.PlayerId) {
return false;
}
return true;
}
#Override
public String toString(){
return hashCode()+" "+getID() +" "+getName()+" "+getSalary();
}
// generic method StoreplayerDetails
public <T> void StoreplayerDetails( HashMap<Integer,T> inputMap ) {
// save elements into text file
PrintWriter pw = null;
try {
pw = new PrintWriter(new FileOutputStream("OutPut.txt"));
for(T element : inputMap.values())
pw.println(element);
pw.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(MainProgram.class.getName()).log(Level.SEVERE, null, ex);
} finally {
pw.close();
}
}
#Override
public int compareTo(player other) {
if(this.salary>other.salary)
return 1;
else
if(this.salary<other.salary)
return -1;
return 0;
}
public interface Update {
public <T> void updateSalaries( HashMap<Integer,player> inputMap);
}
}
create an interface named update in the player class ,create a generic method named updateSalaries in the interface that takes a HashMap as input and returns a Queue of player objects after updating the salaries of players by adding 500 to each one's salary .
in the mainprogram class implement the method updatesalaries as a lamdba expression .in the mainprogram class,print the elements in the returned queue .
I tried it as follows but it did not work out:
#Override
public <T> void updateSalaries(HashMap<Integer, player> map) {
map.replaceAll((k,player.getSalary()) -> player.getSalary()+500;
System.out.println("new map"+map);
}
This is the full code in the main class
import java.util.HashMap;
import player.player.Update;
public class MainProgram implements Update{
public static void main(String[] args) {
HashMap< Integer,player> Keys = new HashMap<>();
player p1 =new player(1);
p1.setName("Ali");
p1.setSalary(5000);
player p2 =new player(2);
p2.setName("Sayed");
p2.setSalary(7000);
player p3 =new player(3);
p3.setName("soha");
p3.setSalary(3000);
Keys.put(1, p1);
Keys.put(2, p2);
Keys.put(3, p3);
// p1.StoreplayerDetails(Keys);
MainProgram m = new MainProgram();
m.updateSalaries(Keys);
}
#Override
public <T> void updateSalaries(HashMap<Integer, player> map) {
map.replaceAll((k,player.getSalary()) -> player.getSalary()+500;
System.out.println("new map"+map);
}
}
Is there any help in solving this?
In your code snippet you have the following line of code:
map.replaceAll((k,player.getSalary()) -> player.getSalary()+500;
Let's take this apart piece by piece:
map.replaceAll This method lets you replace all the values in a map. I believe you want to manipulate the values that are already there, instead.
(k,player.getSalary()) This is where you name the variables that the lambda will dump values into. You aren't supposed to supply numbers here, you are supposed to be receiving numbers. You likely want (k, p), where k will be set to the key (an Integer) and p will be set to the value (a player).
player.getSalary()+500 This returns an int. The replaceAll method requires that you return the value type, which in this case is player.
You forgot to include a close parenthesis at the end.
I believe you want to use this line of code instead, which mitigates all of the above errors:
map.forEach((k, p) -> p.setSalary(p.getSalary() + 500));

How to use abstract method TreeModel in zk framework?

My question just very short."How to use abstract method or example used in this method?"
This method is from org.zkoss.zul.TreeModel
tmtAtasan = new TreeModel<Map<String,Object>>() {
#Override
public void addTreeDataListener(TreeDataListener arg0) {
// TODO Auto-generated method stub
}
#Override
public Map<String, Object> getChild(int[] arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public Map<String, Object> getChild(Map<String, Object> arg0,
int arg1) {
// TODO Auto-generated method stub
return null;
}
#Override
public int getChildCount(Map<String, Object> arg0) {
// TODO Auto-generated method stub
return 0;
}
#Override
public int getIndexOfChild(Map<String, Object> arg0,
Map<String, Object> arg1) {
// TODO Auto-generated method stub
return 0;
}
#Override
public int[] getPath(Map<String, Object> arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public Map<String, Object> getRoot() {
// TODO Auto-generated method stub
return null;
}
#Override
public boolean isLeaf(Map<String, Object> arg0) {
// TODO Auto-generated method stub
return false;
}
#Override
public void removeTreeDataListener(TreeDataListener arg0) {
// TODO Auto-generated method stub
}
};
I am badly stuck into this. Any help would be really appreciateable.
Thanks in advance!
Ok so from what I understand you just want to use a generic TreeModel without needing to redefine specific behaviors.
So let's imagine your model is a list of Employee beans like :
public class Employee {
private String name;
private List<Employee> listSubordinates = new ArrayList<Employee>();
public Employee(String pName) {
name = pName;
}
public void setName(String pName) {
this.name = pName;
}
public String getName() {
return name;
}
public List<Employee> getListSubordinates() {
return listSubordinates;
}
public void setListSubordinates(List<Employee> pListSubordinates) {
this.listSubordinates = pListSubordinates;
}
}
For this example, we'll imagine you have retrieved a list of employee that are sorted by hierarchy already (to simplify the example).
Employee boss1 = new Employee("Boss1");
Employee sub1 = new Employee("Sub1");
boss1.getListSubordinates().add(sub1);
Employee sub2 = new Employee("Sub2");
boss1.getListSubordinates().add(sub2);
Employee boss2 = new Employee("Boss2");
Employee sub3 = new Employee("Sub3");
boss2.getListSubordinates().add(sub3);
List<Employee> listBosses = Arrays.asList(boss1, boss2);
Again this is a simple example with just one level of hierarchy, if you had a variable level of hierarchy the following code would have to be recursive.
// Build the list of the nodes sorted by hierarchy
List<DefaultTreeNode<Employee>> firstLevelNodes = new ArrayList<DefaultTreeNode<Employee>>();
// For each employee of the highest level
for (Employee boss : listBosses) {
// Build the list of its sub employee
List<DefaultTreeNode<Employee>> listSubordinates = new ArrayList<DefaultTreeNode<Employee>>();
for (Employee subordinate : boss.getListSubordinates()) {
listSubordinates.add(new DefaultTreeNode<Employee>(subordinate));
}
// Then build the boss node with its data and its children nodes
DefaultTreeNode<Employee> bossNode = new DefaultTreeNode<Employee>(boss, listSubordinates);
// And add it to the list of first level nodes
firstLevelNodes.add(bossNode);
}
// Build the ROOT, a 'technical' node containing the nodes of the tree.
DefaultTreeNode<Employee> root = new DefaultTreeNode<Employee>(null, firstLevelNodes);
// Create the TreeModel
TreeModel treeModel = new DefaultTreeModel<Employee>(root);
And now you just have to set the TreeModel to your Tree component.
Hope this helps.

Sorting with abstract class

I had some difficulties in sorting in decreasing order the elements of the following abstract class and its extensions.
package BankServices;
public abstract class Operation {
public Operation (int date, double value){
}
public abstract double getValue();
public abstract int getDate();
public abstract String toString();
}
package BankServices;
public class Deposit extends Operation {
private int date;
private int value;
public Deposit(int date, double value) {
super(date, value);
// TODO Auto-generated constructor stub
}
#Override
public String toString() {
// TODO Auto-generated method stub
return date + "," + value + "+";
}
#Override
public double getValue() {
// TODO Auto-generated method stub
return value;
}
#Override
public int getDate() {
// TODO Auto-generated method stub
return date;
}
}
package BankServices;
public class Withdrawal extends Operation{
private int date;
private double value;
public Withdrawal(int date, double value) {
super(date, value);
// TODO Auto-generated constructor stub
}
#Override
public String toString() {
// TODO Auto-generated method stub
return date + "," + value + "-";
}
#Override
public double getValue() {
// TODO Auto-generated method stub
return value;
}
#Override
public int getDate() {
// TODO Auto-generated method stub
return date;
}
}
I had to implement these methods of the main class returning sorted lists in descending order:
public List<Operation> getMovements() {
Collections.sort(operations, new Comparator<Operation>(){
public int compare(Operation a, Operation b){
return (int) (b.getDate() - a.getDate());
}
});
return operations;
}
public List<Deposit> getDeposits() {
Collections.sort(deposits, new Comparator<Operation>(){
public int compare(Operation a, Operation b){
return (int) (b.getValue() - a.getValue());
}
});
return deposits;
}
public List<Withdrawal> getWithdrawals() {
Collections.sort(withdrawals, new Comparator<Operation>(){
public int compare (Operation a, Operation b){
return (int) (b.getValue() - a.getValue());
}
});
return withdrawals;
}
the first one returns a List ordered by date, while getDeposits() and getWithdrawals() return List and List ordered by value..
Could you please suggest how to make it work without mistakes and failures?
Thank you very much in advance.
Instead of this - use compareTo(...) method which is both on Double and Date, so for example:
Collections.sort(withdrawals, new Comparator<Operation>(){
public int compare (Operation a, Operation b){
return Double.valueOf(b.getValue()).compareTo(Double.valueOf(a.getValue()));
}
});
Still, your code should work, except for some weird data you can have there... But not for real life data I think
EDIT: I was wrong, your code would only work if difference between doubles would be over 1.

When printing list it is gibberish [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java Object default toString
Why is it when I print my List from filereader it is [myServiceOrder#3bc1cac, myServiceOrder#32fe621e, myServiceOrder#5adbb9b9, myServiceOrder#f7e4f49, myServiceOrder#2d874991, myServiceOrder#ceee5f1, myServiceOrder#183a37d9]
public class myServiceOrder implements ServiceOrder, Comparable<myServiceOrder>{
private int number=0;
private String ownerName="";
private String make="";
private String model="";
private int year=0;
public myServiceOrder(int number, String ownerName, String make, String model, int year) {
this.number=number;
this.ownerName=ownerName;
this.make=make;
this.model=model;
this.year=year;
}
public myServiceOrder() {
// TODO Auto-generated constructor stub
}
#Override
public void setOrderNum(int orderNumber) {
number=orderNumber;
}
#Override
public void setYear(int year) {
this.year=year;
}
#Override
public void setOwner(String ownerName) {
this.ownerName=ownerName;
}
#Override
public void setMake(String make) {
this.make=make;
}
#Override
public void setModel(String model) {
this.model=model;
}
#Override
public String getOwner() {
return ownerName;
}
#Override
public String getMake() {
return make;
}
#Override
public String getModel() {
// TODO Auto-generated method stub
return model;
}
#Override
public int getOrderNum() {
// TODO Auto-generated method stub
return number;
}
#Override
public int getYear() {
// TODO Auto-generated method stub
return year;
}
#Override
public String getMakeModelYear() {
// TODO Auto-generated method stub
return make+ " "+ model+ " "+ year+ " ";
}
#Override
public boolean equals(ServiceOrder otherServiceOrder) {
if (getOrderNum()==otherServiceOrder.getOrderNum())
return true;
else
return false;
}
#Override
public int compareTo(ServiceOrder otherServiceOrder, int key) {
int comparisonResult=0;
if(key==1)
{
if(getOrderNum()< otherServiceOrder.getOrderNum())
comparisonResult= -1;
if(getOrderNum()== otherServiceOrder.getOrderNum())
comparisonResult= 0;
if(getOrderNum()> otherServiceOrder.getOrderNum())
comparisonResult= 1;
}
else if(key==2)
{
comparisonResult = getOwner().compareTo(otherServiceOrder.getOwner());
}
else if(key==3)
{
comparisonResult = getOwner().compareTo(otherServiceOrder.getOwner());
}
return comparisonResult;
}
#Override
public int compareTo(myServiceOrder arg0) {
// TODO Auto-generated method stub
return 0;
}
}
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class List extends LinkedList<myServiceOrder> {
private static LinkedList<myServiceOrder> newList = new LinkedList();
public void Print() throws Exception
{
System.out.println(newList);
}
public LinkedList<myServiceOrder> createServiceOrder(File inFile) throws Exception {
int number=0;
String ownerName="";
String make="";
String model="";
int year=0;
myServiceOrder serviceList = new myServiceOrder();
Scanner fileScan=new Scanner(inFile);
while (fileScan.hasNext())
{
String ignore;
number = fileScan.nextInt();
//System.out.println(number);
ignore = fileScan.nextLine(); // ignore the newline
ownerName = fileScan.nextLine();
// System.out.println(ownerName);
make = fileScan.nextLine();
// System.out.println(make);
model = fileScan.nextLine();
// System.out.println(model);
year = fileScan.nextInt();
// System.out.println(year);
ignore = fileScan.nextLine(); // ignore the newline
serviceList = new myServiceOrder( number, ownerName, make, model, year);
newList.add(serviceList);
}
fileScan.close();
// System.out.println(newList.viewAll());
return newList;
}
}
Ok I see, my was I dense. I also have a second question: I have to sort the list three different ways depending in my GUI what option I select, I assume that I implement Comparable, but in my compareTo interface it is compareTo(Object o, int key). How can I use that key if the sort method is just Object o. Should I try using a Comparator? if my key=1 how can I tell it to sort that way in my List class?
Classic case of a missing override of the toString() method in your myServiceOrder class.
Take a look here for examples in implementation. This page and Rohit's answer give explanations as to why you need to override toString().
Argh didn't see your second question until now when it's very late:
See this question and this question on the differences between using the Comparable interface vs using the Comparator interface.
How would Java know how you want myService objects to be printed? You can tell it by overriding toString:
#Override
public String toString() {
return "myServiceObject#" + number + "[" + ownername + ", " + make + ", " + model + ", " + year + "]";
}
System.out.println(newList);
This automatically calls the toString() method of the LinkedList class which in turn calls toString() on each of the references in the list (your ServiceOrder objects, in this case). Since you have not provided your own toString() method, the default one in Object is used. This gives the funny output myServiceOrder#3bc1cac which is Java's default way of printing a reference variable. If you wish to see something else, you need to tell Java how to do this by implementing toString() in your ServiceOrder class.
What gets printed is actually the hashcode of the object you print without overriding toString method.. Now since you're printing LinkedList, you can't do that.. Rather you can iterate over the list and print individual element: -
public void Print() throws Exception
{
for (myServiceOrder so: newList) {
System.out.println(so)
}
}
Now, since serviceOrder is itself an object.. You would need to override your toString() in that class..
#Override
public String toString() {
return this.ownerName + this.make + "[" + this.model + " - " + String.valueOf(this.year) + "]";
}

How to return multiple time value to a class in java?

I have 2 classes 'Main' and 'FOR'. From 'Main' I will call method 'display' in class 'FOR'. 'display' will get multiple String values and return it to 'Main' class. Here the returned values must be displayed.
Only one single value is returned. How to get that multiple values returned?
Main.class
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
FOR obj = new FOR();
String str = obj.display();
System.out.print(str);
}
}
FOR.class
public class FOR {
int j=5;
String hi="hi";
String display()
{
for(int i=0;i<j;i++)
{
System.out.print(hi);
// If I use this I will get 5 times hi.. but I dont
/// want like this. I have to return hi String 5times to main and I have to display
/// but should not call 5 times display() too,by calling one time, I have to return
/// 5 time a string to Main class
}
return hi;
}
}
Desired output is to return 5 values from the method 'display'. Here I have to get 5 times HI .. But I am getting only one time .. the comment inline explains in more detail.
You can use List.
Example:
import java.util.List;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
FOR obj=new FOR();
List<String> str= obj.display();
for(String v: str) {
System.out.print(v);
}
}
}
import java.util.List;
import java.util.ArrayList;
List<String> display() {
int j=5;
String hi="hi";
List<String> result = new ArrayList<String>();
for(int i=0;i<j;i++) {
result.add(hi);
}
return result;
}
A slightly different and more complicated approach but is useful in certain situations.
public class Main {
public static void main(String[] args) {
FOR obj = new FOR();
String str = obj.display(new ICallback() {
#Override
public void doSomething(String obj) {
// do whatever you want with this
System.out.println("This is being returned for each execution " + obj);
}
});
System.out.print(str);
}
public static interface ICallback
{
void doSomething(String obj);
}
public static class FOR {
int j = 5;
String hi = "hi";
String display(ICallback callback) {
for (int i = 0; i < j; i++) {
callback.doSomething(hi);
}
return hi;
}
}
}

Categories