This is part of JavaUnitTestChallengeSolved. -- DonWells
Now I can try testing this BoundedBuffer class. First, I will try calling put a few times and see what happens. Of course, I need to have access to the private instance variables. I could have added accessors, but for now I am just going to make the variables public. I don't see any reason at this moment not to. I create my first test:
public class PutAloneTest? extends Test { public void run (){ BoundedBuffer buffer = new BoundedBuffer(); try { buffer.put("a");} catch (InterruptedException exception) {}; should(buffer.putAt == 0,"putAt should start at 0"); should(buffer.occupied == 1,"occupied must be 1"); should(buffer.buffer[1].equals("a"),"wrong object in buffer");} }This test fails because I did not understand the code completely. PutAt? should actually start at 1. So I change the test. I run it again and get an abort because of a null condition.
OOPS, I see that I am looking at the wrong location in buffer for the first object. I can change that. My understanding of the put method is growing. I now have:
public void run (){ BoundedBuffer buffer = new BoundedBuffer(); try { buffer.put("a");} catch (InterruptedException exception) {}; should(buffer.putAt == 1,"putAt should start at 1"); should(buffer.occupied == 1,"occupied must be 1"); should(buffer.buffer[0].equals("a"),"wrong object in buffer");}This actually works.
Now I have one test. Let's stretch it a bit. I can call put a couple times and make sure everything goes as I understand it should. I refactor out the common code and get this with five test calls.
public class PutAloneTest? extends Test { public BoundedBuffer buffer; public void run (){ buffer = new BoundedBuffer(); put("a"); checkBuffer("first call, ", 1, 1, 0, "a"); put("b"); checkBuffer("second call, ", 2, 2, 1, "b"); put("c"); checkBuffer("third call, ", 3, 3, 2, "c"); put("d"); checkBuffer("fourth call, ", 4, 4, 3, "d"); put("e"); checkBuffer("fifth call, ", 0, 0, 0, "e");} public void put(String aString){ try { buffer.put(aString);} catch (InterruptedException exception) {};} public void checkBuffer (String aMessage, int aPutAtValue, int anOccupiedValue, int anIndex, String aBufferValue){ should(buffer.putAt == aPutAtValue, errorMessage (aMessage, "putAt should be ", aPutAtValue)); should(buffer.occupied == anOccupiedValue, errorMessage (aMessage, "occupied must be ", anOccupiedValue)); should(buffer.buffer[anIndex].equals(aBufferValue),errorMessage (aMessage, "wrong object in buffer at", anIndex));} public String errorMessage (String aMessage, String anError, int anInt) { return aMessage + anError + new Integer(anInt).toString();} }I run this now and it takes forever. But this is a good thing! Just as I had expected, the thread goes to sleep and never comes back. I will need to change the way I am testing to account for this. But for the sake of this particular test, I am going to just change the last part of the test to:
buffer.occupied = 2; put("e"); checkBuffer("fifth call, ", 1, 3, 0, "e");}This is still a fine test but now I will need to create a test that starts the put in a thread of it's own to test the wait portion. But for now let's look at the take.