HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

FiniteArrayQueue type with interface and unit tests

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
withteststypeinterfaceandfinitearrayqueueunit

Problem

Doing some exercises on basic data structures, I learned about queues, and decided to roll my own to better understand how a basic queue can function. As the name indicates, this Queue is made from a finite (i.e. regular) array. The JavaDoc gives more details throughout.

All this is pretty new to me, so I'm hoping to receive criticism on any and all aspects that can be improved.

Interface & Exceptions:

public interface Queue {
    public int getSize();
    public boolean isEmpty();
    public boolean isFull();
    public void enqueue(Object obj) throws QueueFullException;
    public Object dequeue() throws QueueEmptyException;
}

public class QueueEmptyException extends RuntimeException {
    public QueueEmptyException() {
        super();
    }
    public QueueEmptyException(String message) {
        super(message);
    }
    public QueueEmptyException(String message, Throwable cause) {
        super(message, cause);
    }
}

public class QueueFullException extends RuntimeException {
    public QueueFullException() {
        super();
    }
    public QueueFullException(String message) {
        super(message);
    }
    public QueueFullException(String message, Throwable cause) {
        super(message, cause);
    }
}


FiniteArrayQueue

```
/**
* A FiniteArrayQueue can enqueue 0..N Objects, after which it must dequeue Objects to make room to enqueue
* more Objects. Objects may be dequeued from it until the queue is empty. The size of the queue cannot be changed
* after instantiation.
*/
public class FiniteArrayQueue implements Queue {
private Object[] queue;
private int capacity;
private int head;
private int tail;

/**
* Constructor.
*
* Note that in order for a FiniteArrayQueue to have a "true" capacity of N items,
* its array size must be of (N + 1) to account for not being able to overlap
* the head and tail pointers of the queue (unless the queue is empty).
* @param desiredCapacity : The maxim

Solution

On testing...

Your tests are incomplete, certainly.

Your test on isEmpty only tests two conditions: a newly instantiated queue which has never had anything added to it should return true, and after adding just one thing, it should return false.

  • How does isEmpty do when the queue is full?



  • How does isEmpty do when the queue has had two items added and then one removed?



  • How does isEmpty do when the queue has had two items added and then two removed?



  • How does isEmpty do when it has been filled, emptied, then filled again?



  • How does isEmpty do when our queue is instantiated with a max size of zero?



We can ask a lot of the same questions for isFull.

  • How does isFull do with a newly instantiated queue that has never had any objects added to it?



  • How does isFull do when we've filled it and then removed one or more objects?



  • How does isFull do when we've filled it, removed some objects, then filled it back to capacity?



  • How does isFull do when we create a queue with max size zero?



We can ask some questions of getSize too. You've only tested on very specific and weird case.

  • Does getSize return the proper value of a newly instantiated array before we've added anything to it?



  • For every call to enqueue, does getSize return the correct value? (Hint: You can assert in a loop)



  • If we have a full queue, try to enqueue, catch the exception, does getSize still return the expected value?



  • For every call to dequeue, does getSize return the correct value?



  • When we've filled, then emptied to zero, does getSize return the correct value?



  • If we have an empty queue, try to dequeue, catch the exception, does getSize still return the expected value (zero)?



How about enqueuing and dequeuing?

Your testEnqueue is testing the wrong thing. That's asserting that getSize works.

The first assertion in testDequeue has the right idea, but the second assertion is testing that isEmpty works.

Neither of these tests test that the proper exception is thrown in the proper conditions.

I would write something called testFirstInFirstOut that runs through lots of iterations and combinations of enqueuing and dequeuing and making sure things are coming out in the order we'd expect them to come out in.

I'd also write a test called testEnqueueException to verify that when we try to enqueue into a full queue, we get an exception.

I'd also write a test called testDequeueException to verify that when we try to dequeue from a full queue, we get an exception.

And most importantly, I'd spend a LOT of time on THIS answer before you even begin to start trying to implement any of the advice from my other answer (or any other answer that addresses anything but testing).

Refactoring has a tendency to introduce regressions. Unit tests prevent regressions. Beefing up your test suite before you start refactoring is a good way to make sure you're introducing as few regressions as possible.

Context

StackExchange Code Review Q#121500, answer score: 13

Revisions (0)

No revisions yet.