JUnit test in Isolation using Mockito - java

I have basic understanding of how to apply Mockito framework.
But when it comes to some real time scenarios I failed to write tests in Isolation(by Mocking the dependent classes).
Can you help me to write Unit test for PriorityQueuePrinter class by Mocking PriorityQueue Implementation(BinaryMaxHeap.java).
I wrote testPriorityQueue() with BinaryMaxHeap object, in this case my test becomes success but I want to achieve the same to mock BinaryMaxHeap so that my test will be Isolate. I think I have to set method behaviours also in my test method.
In short, Priority Queue is the Implementation for BinaryHeapTree and Printer class uses Priority Queue.
Below are the code classes.
public interface PriorityQueue<T extends Comparable<T>> {
int size();
void insert(T element);
T popMax();
}
public class BinaryMaxHeap<T extends Comparable<T>> implements PriorityQueue<T> {
private ArrayList<T> items;
public BinaryMaxHeap() {
items = new ArrayList<T>();
}
public int size() {
return items.size();
}
public void insert(T element) {
items.add(element);
shiftUp();
}
public T popMax() {
if (items.size() == 1) {
return items.remove(0);
}
T hold = items.get(0);
items.set(0, items.remove(items.size()-1));
shiftDown();
return hold;
}
/*
* place newly added element in correct position in binary tree
*/
private void shiftUp() {
int k = items.size() - 1;
while (k > 0) {
int p = (k-1) / 2; // get parent element index
T child = items.get(k);
T parent = items.get(p);
if (child.compareTo(parent) > 0) {
// parent and child are not in correct position, need to swap
items.set(k, parent);
items.set(p, child);
k = p;
} else {
break;
}
}
}
private void shiftDown() {
int k = 0;
int l = 2*k+1; // left leaf node
while (l < items.size()) {
int max = l; // assume left node as max element
int r = l+1; // right leaf node
if (r < items.size()) {
if (items.get(r).compareTo(items.get(l)) > 0) {
max++; // identify max element in leaf nodes
}
}
T parent = items.get(k);
T child = items.get(max);
if (parent.compareTo(child) < 0) {
// parent element is less than leaf node, need to swap it
T temp = items.get(k);
items.set(k, items.get(max));
items.set(max, temp);
k = max;
l = 2*k+1;
} else {
break;
}
}
}
}
public interface Printer {
public <T extends Comparable<T>> String asSortedString(T... values);
}
public class PriorityQueuePrinter implements Printer {
private PriorityQueue priorityQueue = null;
public <T extends Comparable<T>> PriorityQueuePrinter(PriorityQueue<T> priorityQueue) {
this.priorityQueue = priorityQueue;
}
public <T extends Comparable<T>> String asSortedString(T... values) {
//PriorityQueue<T> priorityQueue =
addElements(values);
//return getSortedElements();
return null;
}
private <T extends Comparable<T>> void addElements(T... values) {
//PriorityQueue<T> priorityQueue = new BinaryMaxHeap<T>();
for (T element : values) {
priorityQueue.insert(element);
}
//return priorityQueue;
}
public int size() {
return priorityQueue.size();
}
private String getSortedElements() {
StringBuilder sortedElements = new StringBuilder();
boolean isFirstElement = true;
while(priorityQueue.size() > 0) {
if (!isFirstElement) {
sortedElements.append(",");
}
isFirstElement = false;
sortedElements.append(priorityQueue.popMax());
}
return sortedElements.toString();
}
public static void main(String a[]) {
PriorityQueuePrinter p = new PriorityQueuePrinter(new BinaryMaxHeap<Integer>());
String sortedElements = p.asSortedString(1,4,6,3,2);
System.out.println(sortedElements);
}
}
Below is the sample test code tried but not able to complete.
public class PrinterTest {
#Mock
PriorityQueue<Integer> mockPriorityQueue; // mock object
PriorityQueue<Integer> priorityQueue;
#Test
public void testPriorityQueueWithMock() {
PriorityQueuePrinter printer = new PriorityQueuePrinter(mockPriorityQueue);
String s = printer.asSortedString(5,3,6);
assertEquals("6,5,3", s);
}
#Ignore
public void testPriorityQueue() {
priorityQueue = new BinaryMaxHeap<Integer>();
PriorityQueuePrinter printer = new PriorityQueuePrinter(priorityQueue);
String s = printer.asSortedString(5,3,6);
assertEquals("6,5,3", s);
}
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#After
public void tearDown() throws Exception {
System.out.println("==tearDown==");
}
}
#Before
public void setUp() throws Exception {
//mockPriorityQueue = new BinaryMaxHeap<Integer>();
MockitoAnnotations.initMocks(this);
}
}

Related

How to create generic code for objects of different types

I have an entity that has as children several lists of objects that, although they have different classes, all have the order attribute, in several parts I end up with repeated code, for example in one part I need to order the lists by that attribute and I cannot simplify because they are of different type.
The relevant part of the entity is this:
contenido={
"educaciones":[
{
...
"orden":0
},{
...
"orden":1
}
],
"experiencias":[
{
...
"orden":0
},{
...
"orden":1
}
]
},
...
The code I would like to simplify:
if(tipo.equals("experiencias")){
List<Experiencia> iterable=contenido.getExperiencias();
for(int i = 0; i < iterable.size(); i++){
iterable.get(i).setOrden( orden.get(i) ); //orden = [0,3,5,...]
}
iterable.sort((it1,it2)-> it1.getOrden().compareTo(it2.getOrden()));
}else if(tipo.equals("educaciones")){
List<Educacion> iterable=contenido.getEducaciones();
for(int i = 0; i < iterable.size(); i++){
iterable.get(i).setOrden( orden.get(i) );
}
iterable.sort((it1,it2)-> it1.getOrden().compareTo(it2.getOrden()));
}else if...
Is there a way to create a code that is more generic and supports different objects?
Create an interface for the methods that are common between all you classes:
interface HasOrden {
int getOrden();
void setOrden(int i);
}
Each of your classes needs to implement HasOrden.
Then you can declare sortOrden function:
import java.util.ArrayList;
import java.util.List;
interface HasOrden {
int getOrden();
void setOrden(int i);
}
class Experiencia implements HasOrden {
private final String name;
int orden;
public Experiencia(String name) {
this.name = name;
}
#Override
public int getOrden() {
return orden;
}
#Override
public void setOrden(int i) {
orden = i;
}
public String toString() {
return name;
}
}
public class Eg {
static void sortOrden(List<? extends HasOrden> l, List<Integer> order) {
if (l.size() != order.size()) {
throw new RuntimeException("length mismatch");
}
for (int i = 0; i < l.size(); i++) {
l.get(i).setOrden(order.get(i));
}
l.sort((it1,it2)-> Integer.compare(it1.getOrden(), it2.getOrden()));
}
public static void main(String[] args) {
List<Experiencia> items = new ArrayList<>(List.of(new Experiencia("a"), new Experiencia("b")));
List<Integer> order = List.of(2,1);
sortOrden(items, order);
System.out.println(items);
}
}
You can call sortOrden on any list of HasOrden instances.
you can try to create a List<?> - list with a dynamic type outside of your if else block and move your duplicated code outside too and at the end of the if else block. In addition, you have to create a common class or some interface for your classes, which holds all the common field you needed
public class Main {
public static class Something {
private Integer sth;
public Integer getSth() {
return sth;
}
public void setSth(Integer sth) {
this.sth = sth;
}
}
public static class ThisClass extends Something {
private Integer num;
public ThisClass(Integer num) {
this.num = num;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
}
public static class ThatClass extends Something {
private String str;
public ThatClass(String str) {
this.str = str;
}
public String getStr() {
return str;
}
public void setNum(String str) {
this.str = str;
}
}
public static List<? extends Something> sortList(Class<?> itemClass, List<? extends Something> list)
throws Exception {
for(int i = 0; i < list.size(); i++){
list.get(i).setSth(i);
}
list.sort((it1,it2)-> it1.getSth().compareTo(it2.getSth()));
return list;
}
public static void main(String[] args) {
System.out.println("Hello World");
List<? extends Something> someList = new ArrayList<>();
boolean check = true;
if(check) {
someList = Arrays.asList(new ThisClass(1),new ThisClass(1),new ThisClass(1),new ThisClass(1));
} else {
someList = Arrays.asList(new ThatClass("a"), new ThatClass("a"),new ThatClass("a"),new ThatClass("a"));
}
try {
someList = sortList(ThisClass.class, someList);
for(int i = 0; i < someList.size(); i++){
System.out.println(someList.get(i).getSth());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Override Integer compareTo? Or trick it?

I am trying to write a generic heap class.
import java.util.ArrayList;
public class heap<T extends Comparable<T>>
{
private ArrayList<T> h;
private int size;
public heap()
{
h = new ArrayList<T>();
h.add(null);
size = 0;
}
public T getMin()
{
return h.get(1);
}
public T popMin()
{
T tmp = getMin();
h.set(1, h.get(size));
size--;
sift(1);
return tmp;
}
public void insert(T key)
{
h.add(key);
percolate(++size);
}
public int getSize()
{
return this.size;
}
private int getLeftSon(int i)
{
return (i<<1<=size)? i<<1 : 0;
}
private int getRightSon(int i)
{
return ((i<<1)+1<=size)? (i<<1)+1 : 0;
}
private int getFather(int i)
{
return ((i>>1)!=0)? i>>1 : 0;
}
private void swap(int i, int j)
{
T tmp = h.get(i);
h.set(i, h.get(j));
h.set(j, tmp);
}
private void sift(int i)
{
int son;
do {
son = 0;
if (getLeftSon(i) != 0)
{
son = getLeftSon(i);
if (getRightSon(i) != 0 && h.get(getRightSon(i)).compareTo(h.get(getLeftSon(i))) > 0)
son = getRightSon(i);
if (h.get(son).compareTo(h.get(i)) <= 0)
son = 0;
}
if (son!=0) {
swap(i, son);
i = son;
}
} while (son!=0);
}
private void percolate(int i)
{
T key = h.get(i);
while ((i > 1) && (key.compareTo(h.get(getFather(i))) > 0))
{
h.set(i, h.get(getFather(i)));
i = getFather(i);
}
h.set(i, key);
}
}
All good. It works like a charm. Excepting one thing: if I work with Integers I don't have 'access' to the method compareTo from Integer. meaning that I can not override it's behaviour. I will always have a Max heap this way. Can Integer compareTo by override (I don't think it can)?
So what can I do apart from creating another class MyInteger extends Integer{...} and override it there.
You could make your heap accept a Comparator in constructor and then provide a Comparator that reverses the order.
That's what the Comparator is for actually - defining an ordering that's not a natural one for the given class, being able to define multiple orderings of the same class, or indeed defining an ordering for a class you cannot modify.
The approach of accepting a comparator at construction time can be seen in TreeSet for example.
Example code stub:
public class Heap<T> { /* no need for items to extend Comparable anymore */
private final Comparator<T> cmp;
public Heap(Comparator<T> cmp) {
this.cmp = cmp;
...
}
...
}
... and then use cmp.compare(item1, item2) wherever you now use item2.compareTo(item2).

Java Generic class doesn't display the objects i pass into it

I am trying to build a simple generic class that uses generic objects in java. everything compiles fine, but when i run the code, it doesn't display the objects i passed to it.
Here is my code:
public class ListDriver {
public static void main(String[] args) {
List<String> glist = new List<String>(10);
glist.add("milk");
glist.add("eggs");
System.out.println("Grocery List" + glist.toString());
}
public class List<T> {
private T[] datastore;
private int size;
private int pos;
public List(int numElements) {
size = numElements;
pos = 0;
datastore = (T[]) new Object[size];
}
public void add(T element) {
datastore[pos] = element;
}
public String toString() {
String elements = "";
for (int i = 0; i < pos; ++i) {
elements += datastore[i] + "";
}
return elements;
}
}
}
You don't increment your pos variable, so you're always adding in the same place. Try
public void add(T element) {
datastore[pos++] = element;
}
Your add method always replaces the element in position 0 (zero). You forgot to increment pos (pos++;)

Inexplicable Issue with Add Method of a Simple Binary Tree

My binary tree looks pretty close to my class materials, but when I print to the console or check for contains(), any adds I'm doing aren't registered.
I don't have a great understanding of static and the debugger is giving me a hint about making a static reference to non-static variable overallRoot, but everything compiles without error or warning in eclipse.
public class BSTSimpleSet<E extends Comparable<E>> implements SimpleSet<E> {
private GTNode<E> overallRoot;
private int size;
public static void main(String[] args) {
BSTSimpleSet<Integer> main = new BSTSimpleSet<Integer>(2);
main.toString();
main.add(3);
main.toString();
main.add(4);
main.toString();
main.add(5);
main.toString();
System.out.print(main.contains(3));
}
public BSTSimpleSet() {
size = 0;
}
public BSTSimpleSet(E input) {
overallRoot = new GTNode<E>(input);
size = 1;
}
public boolean add(E e) {
return add(e, overallRoot);
}
private boolean add(E e, GTNode<E> root) {
if (root == null) {
root = new GTNode<E>(e);
size++;
return true;
} else {
int compare = e.compareTo(root.data);
if (compare == 0) {
return false;
} else if (compare < 0) {
return add(e, root.left);
} else {
return add(e, root.right);
}
}
}
public void clear() {
overallRoot = null;
}
public boolean contains(E e) {
return contains(e, overallRoot);
}
private boolean contains(E e, GTNode<E> root) {
if (root == null) {
return false;
} else {
int compare = e.compareTo(root.data);
if (compare == 0) {
return true;
} else if (compare < 0) {
return contains(e, root.left);
} else {
return contains(e, root.right);
}
}
}
public boolean isEmpty() {
if (overallRoot == null) {
return false;
} else {
return true;
}
}
public int size() {
return size;
}
public String toString() {
this.toString(overallRoot, 0);
return null;
}
private void toString(GTNode<E> root, int level) {
if (root != null) {
for (int i = 0; i < level; i++) {
System.out.print(" ");
}
System.out.println(root.data);
toString(root.left, level + 1);
toString(root.right, level + 1);
} else {
for (int i = 0; i < level; i++) {
System.out.print(" ");
}
System.out.println("_");
}
}
private static class GTNode<E extends Comparable<E>> {
public E data;
public GTNode<E> left;
public GTNode<E> right;
public GTNode(E input) {
this(input, null, null);
}
public GTNode(E input, GTNode<E> lNode, GTNode<E> rNode) {
data = input;
left = lNode;
right = rNode;
}
}
}
This code does absolutely nothing.
private boolean add(E e, GTNode<E> root) {
if (root == null) {
root = new GTNode<E>(e);
size++;
return true;
}
...
Java passes in the Object Reference to a method. If you change the Reference, that will not
be propagated back to the calling method. If you change what the Reference refers to
that will be propagated back.
eg
// arrays behave the same way so using them to illustrate.
public void callMethods(){
int[] array = new int[1];
array[0] = 0;
doesNotChange(array);
System.out.println(array[0]);// will print 0
doesAChange(array);
System.out.println(array[0]);// will print 1
}
public void doesNotChange(int[] myArray){
myArray = new int[1];
myArray[0] = 1;
}
public void doesAChange(int[] myArray){
myArray[0] = 1;
}
To avoid these sorts of things I recommend always setting method parameters final.
The GTNode class shouldn't be static. Static classes are classes with only static methods, which means they don't have to be instantiated. The prototypical example of this is the java.lang.Math class: You don't need to call something like Math m = new Math(); m.cos(); to get the cosine, you just call Math.cos(). Since you're creating multiple instances of the GTNode class, make it non-static and you should be good.

Java Generics Question

Queue12 is an interface, QueueImp12 is an implementation of Queue12. So i'm trying to test my QueueImp12 but when i run it(it compiles) in eclipse my output gets terminated in console. I believe I created ringBuffer correctly. If my test looks fine, then something must be wrong with my implementation or eclipse. Thanks
import java.util.NoSuchElementException;
public class QueueImpl12<T> implements Queue12<T>
{
private int _size, _backIdx, _frontIdx;
private static final int _defaultCapacity = 128;
private T[] _ringBuffer;
public QueueImpl12(int capacity)
{
_ringBuffer = (T[]) new Object[capacity];
clear();
}
public QueueImpl12()
{
_ringBuffer = (T[]) new Object[_defaultCapacity];
clear();
}
private int wrapIdx(int index)
{
return index % capacity();
}
public void clear()
{
_backIdx = 0;
_frontIdx = 0;
_size = 0;
}
#Override
public int capacity()
{
// TODO Auto-generated method stub
return _ringBuffer.length;
}
#Override
public int size()
{
// TODO Auto-generated method stub
return _size;
}
#Override
public boolean enqueue(T o)
{
//add o to back of queue
if(_ringBuffer.length == _size)
{
return false;
}
_ringBuffer[_backIdx] = o;
_backIdx = wrapIdx(_backIdx + 1 );
_size++;
return true;
}
#Override
public T dequeue()
{
if(_size == 0) //empty list
{
throw new NoSuchElementException();
}
T tempObj = _ringBuffer[_frontIdx]; //store frontIdx object
_ringBuffer[_frontIdx] = null;
_frontIdx++;
_size--;
return tempObj;
}
#Override
public T peek()
{
return _ringBuffer[_frontIdx];
}
}
public class P3test
{
public static<T> void main(String[] args)
{
final Queue12<T> ringBuffer = new QueueImpl12<T>();
T o = (T) new String("this");
ringBuffer.enqueue(o); //add element to the back
ringBuffer.dequeue(); //remove/return element in the front
}
}
That 'terminated' you have been seeing lately is the expected behavior when your program finishes.
Put some System.outs or asserts to verify that your code runs (here it runs, with some awful cast warnings, but runs)
final Queue12<T> ringBuffer = new QueueImpl12<T>();
T o = (T) new String("this");
ringBuffer.enqueue(o); //add element to the back
System.out.println(ringBuffer.peek());//this should print 'this' in the console\
//assertEquals('this', ringBuffer.peek());
ringBuffer.dequeue(); //remove/return element in the front
Learn how to use generics and tests. And don't put generic argument in main function, is is useless there.

Categories