I have this contract:
public interface Stack<T> { void push(T object); T pop(); int size(); }
I am curious what you think about my test of the size()
and pop()
in order to prevent bugs (underlying data structure in not being cleaned) in implementation like below:
Implementation:
public class StackImpl implements Stack<Object> { private int size; private Object data[]; @Override public void push(Object object) { data[size] = object; size++; } @Override public Object pop() { --size; return data[size]; } @Override public int size() { return size; } }
Test:
public class StackTest { @Test public void pushTwoObjectsToEmtyStackCheckThatSizeIsTwo() { pushObjectsInOrder(OBJECT_A, OBJECT_B); assertEquals(2, stack.size()); } @Test public void pushTwoObjectToEmptyStackAndPopTheSameObjectsInReversedOrder() { pushObjectsInOrder(OBJECT_A, OBJECT_B); assertEquals(OBJECT_B, stack.pop()); assertEquals(OBJECT_A, stack.pop()); } @Test(expected=IllegalArgumentException.class) public void stackDoesntAcceptNullAndThrowExcpetion() { stack.push(null); } @Before public void setUp() throws Exception { stack = new StackImpl(); } private void pushObjectsInOrder(Object... objects) { for (Object object : objects) { stack.push(object); } } private static final Object OBJECT_A = new Object(); private static final Object OBJECT_B = new Object(); private Stack<Object> stack; }
I'd like to not focus too much on the implementation itself, like whether it should be List
or array etc. Assume that you defined interface and going to give to implement it to other guy. Since you defined the contract you are the one who writes a unit test.