getRequests() must return an Iterable of arrays - java

my code:
#RunWith(Parameterized.class)
public class FreshResultCompareRunner2 {
//This is called before #BeforeClass !
#Parameterized.Parameters
public static Collection getRequests() throws IOException {
injector = Guice.createInjector(new MainModule());
initStaticFromInjector();
initTestInput();
return OrganizeTestParameterizedInput();
}
private static void initTestInput() throws IOException {
}
private static Collection OrganizeTestParameterizedInput() {
Object[] objectMatrix = new Object[100];
for (int i = 0; i < 100; i++) {
objectMatrix[i] = i;
}
return Arrays.asList(objectMatrix);
}
returns the following exception:
getRequests() must return an Iterable of arrays
how can i run the parameterized junit with increasing int only as input param?
say run the same test for i=0 ...100 ?
update
I have tried
//This is called before #BeforeClass !
#Parameterized.Parameters
public static Collection<int[]> getParameters() {
injector = Guice.createInjector(new MainModule());
initStaticFromInjector();
int numOfChunks = 3;//routingResponseShortRepository.getNumOfBaseLineChunks();
//might be less
int totalResponses = numOfChunks * globalSettings.requestsChunkSize;
Collection<int[]> params = new ArrayList<>(totalResponses);
for(int i = 1; i <= totalResponses; ++i) {
params.add(new int[] { i });
}
return params;
}
//takes the next matrix row from OrganizeTestParameterizedInput()
public FreshResultCompareRunner2(int responseId) {
this.responseId = responseId;
}
and still get an error:
java.lang.Exception: com.waze.routing.automation.runners.FreshResultCompareRunner2.getParameters() must return an Iterable of arrays.
at org.junit.runners.Parameterized.parametersMethodReturnedWrongType(Parameterized.java:343)

Junit 4.12+ does not has this restriction anymore. So if you develop your tests with JUnit 4.12+ and then execute those test with 4.11- you will also get this error message.
See JUnit 4.12 release notes for more details.

For parametrized tests, JUnit passed the test parameters to the constructor of the test class. Because a constructor can take more than one single argument, JUnit expects every parameter set to be an array. The elements of the array must conform to the constructor arguments.
So your configuration method must return an Iterable of arrays, e.g. Collection<Object[]>. In your case, you just have one single parameter per run, so your array will have a length of 1:
#Parameterized.Parameters
public static Collection<Object[]> getParameters() {
Collection<Object[]> params = new ArrayList<>(100);
for(int i = 1; i <= 100; ++i) {
params.add(new Object[] { i });
}
return params;
}
Also note that your configuration method should never do any initialization as your method seems to do! Initialization is solely done in #Before or #BeforeClass!

Related

Mockito : Testing void methods gives InvalidUseOfMatchersException

I'm having problems with two void methods. In encouragedVenturesScoring I've followed this answer mocking an arraylist that will be looped in a for loop and haven't mocked the list, but passed a real list and added mocked objects.
Mockito gives me an InvalidUseOfMatchersException on this line
verify(effectList.get(Mockito.anyInt())).execute(playerHandler);
There are lots of questions on SO on this exception , and I think it's because of anyInt(). Anyway I changed it to
verify(effectList.get(0)).execute(playerHandler);
And now it's saying Wanted but not invoked effect.execute(playerHandler)
Actually there were zero interactions with this mock
Is it because I put doNothing ?
doNothing().when(effect).execute(playerHandler);
In my second method militaryStrengthScoring() method is there a way to skip the first chunk of code and just test the if..else condition? What would be the best approach to test this method?
Thank you for your time.
This is the class to be tested
public class EndGameScoringBaseController implements EndGameScoringHandler {
private static final int[] TERRITORIES_REWARD = {0,0,1,4,10,20};
private static final int[] CHARACTERS_REWARD = {1,3,6,10,15,21};
private static final int RESOURCES_RATE = 5;
private static final int FIRST_MILITARY_REWARD = 5;
private static final int SECOND_MILITARY_REWARD = 2;
private PlayerHandler player;
public EndGameScoringBaseController(PlayerHandler player) {
super();
this.player = player;
}
#Override
public void encouragedVenturesScoring() {
for (DevelopmentCard card : player.getPlayer().getPersonalBoard().getVentures()) {
for (Effect e : card.getPermanentEffects())
e.execute(player);
}
}
#Override
public void militaryStrengthScoring(GameController game) {
Set<Integer> points = new HashSet<>();
int myPoints = this.player.getPointsHandler().getMilitaryPoints();
for (PlayerHandler p: game.getPlayers()) {
points.add(p.getPointsHandler().getMilitaryPoints());
}
int[] rank = new int[points.size()];
int j = 0;
for (Integer i : points) {
rank[j] = i;
j++;
}
Arrays.sort(rank);
if (rank[rank.length-1] == myPoints) {
player.getPointsHandler().winMilitaryPoints(FIRST_MILITARY_REWARD);
}
else if (rank[rank.length-2] == myPoints) {
player.getPointsHandler().winVictoryPoints(SECOND_MILITARY_REWARD);
}
}
Tested method for encouragedVenturesScoring
#Test
public void encouragedVenturesScoringTest() {
//given
List<DevelopmentCard> ventureList;
ventureList = Arrays.asList(developmentCard, developmentCard);
when(playerHandler.getPlayer().getPersonalBoard().getVentures()).thenReturn(ventureList);
List<Effect> effectList;
effectList = Arrays.asList(effect, effect);
when(developmentCard.getPermanentEffects()).thenReturn(effectList);
doNothing().when(effect).execute(playerHandler);
//when
endgameController.encouragedVenturesScoring();
//then
verify(effectList.get(Mockito.anyInt())).execute(playerHandler);
}
Incomplete tested method for militaryStrengthScoring
#Test
public void militaryStrengthScoringTest() {
//given
when(playerHandler.getPointsHandler().getMilitaryPoints()).thenReturn(4);
doNothing().when(playerHandler.getPointsHandler()).winMilitaryPoints(FIRST_MILITARY_REWARD);
//when
endgameController.militaryStrengthScoring(gameController);
//then
/../
}
You're right that this is the problem:
verify(effectList.get(Mockito.anyInt())).execute(playerHandler);
Mockito only allows for calls like any() and anyInt() to stand in for parameters to the mock themselves, due to the internal implementation of matchers.
/* OK */ when(yourMock.yourMethod(anyInt())).thenReturn(42);
/* BAD */ when(yourList.get(anyInt()).yourMethod(0)).thenReturn(42);
/* OK */ verify(yourMock).yourMethod(anyInt());
/* BAD */ verify(yourList.get(anyInt())).yourMethod(0);
The failure with get(0) is likely an actual failure, and may be related to the fact that your encouragedVenturesScoringTest is actually not calling encouragedVenturesScoring, it's calling influencedCharactersScoring. If this continues to give you trouble after fixing that error, in ways related to Mockito, please edit your question.
You can only verify mock objects created by Mockito.
But effectList is a "real" list. Therefore Mockito knows nothing about that object. Thus any attempt to verify that list must fail.
If you want to verify that object - then you have to mock it!
Of course, this means that you have specify all calls that will go to the mocked list.

JMockit - expectation returns old value instead of value associated with private field

When recording an expectation that returns the value of a field, I would expect the returned value to be the value of the field when the actual method was invoked (value of the reference), as opposed to the field's value when the expectation was recorded.
This is the class under test (actually 2 of them):
public class ListObservingCache<T> extends ObservingCache {
public ListObservingCache(Supplier<List<T>> syncFunc, int intervalMillis) {
super(syncFunc, intervalMillis);
}
#SuppressWarnings("unchecked")
#Override
public List<T> getItems() {
return items != null ? Collections.unmodifiableList((List<T>) items) : null;
}
}
public abstract class ObservingCache {
private static final int DEFAULT_CACHE_REFRESH_INTERVAL = 10 * 60 * 1000; // 10 minutes
private static int DEFAULT_CACHE_INITIAL_DELAY = 10 * 60 * 1000; // 10 minutes
private static final int DEFAULT_THREAD_POOL_SIZE = 5;
private static ScheduledExecutorService executor;
protected Object items;
protected ObservingCache(Supplier<? extends Object> syncFunc) {
this(syncFunc, DEFAULT_CACHE_REFRESH_INTERVAL);
}
protected ObservingCache(Supplier<? extends Object> syncFunc, int intervalMillis) {
if (executor == null || executor.isShutdown()) {
executor = Executors.newScheduledThreadPool(DEFAULT_THREAD_POOL_SIZE);
}
Runnable task = () -> {
Object result = syncFunc.get();
if (result != null) {
items = result;
}
};
task.run(); // First run is blocking (saves a lot of trouble later).
executor.scheduleAtFixedRate(task, DEFAULT_CACHE_INITIAL_DELAY, intervalMillis, TimeUnit.MILLISECONDS);
}
public abstract Object getItems();
}
Here is my test class:
public class ListObservingCacheTest {
List<Integer> provList; // <-- The field I wish to use instead of the "willReturnList()" method
#Mocked
DummyTask mockTask;
#BeforeClass
public static void setupClass() {
ObservingCache.DEFAULT_CACHE_INITIAL_DELAY = 100;
}
#AfterClass
public static void tearDownClass() {
ExecutorService toShutDown = (ExecutorService) getField(ObservingCache.class, "executor");
toShutDown.shutdown();
}
#Before
public void setUp() {
mockTask = new DummyTask(); // Empty list
}
#Test
public void testBasic() throws Exception {
willReturnList(Arrays.asList(1, 2));
ListObservingCache<Integer> obsCache = new ListObservingCache<Integer>(() -> mockTask.acquireList(), 300);
assertEquals(Arrays.asList(1, 2), obsCache.getItems());
willReturnList(Arrays.asList(3, 4, 5));
assertEquals(Arrays.asList(1, 2), obsCache.getItems()); // ObservingCache should still returns the former list because its interval hasn't passed yet
Thread.sleep(300);
assertEquals(Arrays.asList(3, 4, 5), obsCache.getItems()); // ObservingCache should now return the "new" list, as its interval has passed and the task has been executed again
}
/**
* Instructs the mock task to return the specified list when its
* acquireList() method is called
*/
private void willReturnList(List<Integer> list) {
new Expectations() {{ mockTask.acquireList(); result = list; }};
}
/**
* Simulates an ObservingCache "real-life" task. Should never really be
* called (because it's mocked).
*/
class DummyTask {
private List<Integer> list;
public List<Integer> acquireList() {
return list;
}
}
}
This test passes, but I would like a more elegant way to set the expectation for the return value of the acquireList() method, as this kind of "willReturn" methods would become a maintenance nightmare once I have more than one of these in the same class.
I'm looking for something similar to the mockito-syntax command:
when(mockTask.acquireList()).thenReturn(provList);
This should always return the current value of the provList field (as opposed to its value when the expectation was recorded).
EDIT:
After going through the documentation, I came up with a solution, using delegates:
new Expectations() {{
mockTask.acquireList();
result = new Delegate<List<Integer>>() {
List<Integer> delegate() {
return provList; // The private field
}
};
}};
There are 2 problems with this approach:
1. It's not elegant
2. The List<Integer> delegate() method causes a compile-time warning:
The method delegate() from the type new Delegate>(){} is never
used locally
Therefore, still looking for another solution
The problem the OP is trying to "solve" is this: how to simplify the writing of multiple tests in a single test method, when the code under test (here, the obsCache.getItems() method) and the verifications to perform are the same, but the input values are different.
So, this is really a question about how to properly write tests. The basic form of a well-written test is described by the "Arrange-Act-Assert" (AAA) pattern:
#Test
public void exampleOfAAATest() {
// Arrange: set local variables/fields with input values,
// create objects and/or mocks, record expectations.
// Act: call the code to be tested; normally, this is *one* method
// call only.
// Assert: perform a number of assertions on the output, and/or
// verify expectations on mocks.
}
#Test
public void exampleOfWhatisNotAnAAATest() {
// First "test":
// Arrange 1
// Act
// Assert 1
// Second "test":
// Arrange 2 (with different inputs)
// Act again
// Assert 2
// ...
}
Obviously, tests like the second one above are regarded as bad practice, and should not be encouraged.
EDIT: added full test class (below) for the real CUT.
public final class ListObservingCacheTest
{
#Mocked DummyTask mockTask;
final int refreshIntervalMillis = 30;
final List<Integer> initialItems = asList(1, 2);
final List<Integer> newItemsAfterRefreshInterval = asList(3, 4, 5);
#Before
public void arrangeTaskOutputForMultipleCalls() {
new Expectations() {{
mockTask.acquireList();
result = initialItems;
result = newItemsAfterRefreshInterval;
}};
// A trick to avoid a long initial delay before the scheduled task is first
// executed (a better solution might be to change the SUT to read the
// initial delay from a system property).
new MockUp<ScheduledThreadPoolExecutor>() {
#Mock
ScheduledFuture<?> scheduleAtFixedRate(
Invocation inv,
Runnable command, long initialDelay, long period, TimeUnit unit
) {
return inv.proceed(command, 0, period, unit);
}
};
}
#After
public void shutdownTheExecutorService() {
ScheduledExecutorService executorService =
Deencapsulation.getField(ObservingCache.class, ScheduledExecutorService.class);
executorService.shutdown();
}
#Test
public void getTheInitialItemsImmediatellyAfterCreatingTheCache() throws Exception {
// Arrange: empty, as there is nothing left to do beyond what the setup method
// already does.
// Act:
ListObservingCache<Integer> obsCache =
new ListObservingCache<>(() -> mockTask.acquireList(), refreshIntervalMillis);
List<Integer> items = obsCache.getItems();
// Assert:
assertEquals(initialItems, items);
}
#Test
public void getTheSameItemsMultipleTimesBeforeTheCacheRefreshIntervalExpires() throws Exception {
// Act:
ListObservingCache<Integer> obsCache =
new ListObservingCache<>(() -> mockTask.acquireList(), refreshIntervalMillis);
List<Integer> items1 = obsCache.getItems();
List<Integer> items2 = obsCache.getItems();
List<Integer> itemsIfTaskGotToBeCalledAgain = mockTask.acquireList();
List<Integer> items3 = obsCache.getItems();
// Assert:
assertEquals(initialItems, items1);
assertEquals(initialItems, items2);
assertEquals(initialItems, items3);
assertEquals(newItemsAfterRefreshInterval, itemsIfTaskGotToBeCalledAgain);
}
#Test
public void getNewItemsAfterTheCacheRefreshIntervalExpires() throws Exception {
// Act:
ListObservingCache<Integer> obsCache =
new ListObservingCache<>(() -> mockTask.acquireList(), refreshIntervalMillis);
List<Integer> items1 = obsCache.getItems();
Thread.sleep(refreshIntervalMillis);
List<Integer> items2 = obsCache.getItems();
// Assert:
assertEquals(initialItems, items1);
assertEquals(newItemsAfterRefreshInterval, items2);
}
}
When new Expectations() is used in code, an instance of Expectations is created with providedInt value. So, though providedInt is changed in testRegisterInt(), state of Expectations instance does not change. You can try setter to change the result of Expectations.
Ideally, there should not be any logic in stubs. I would rather create multiple stubs in multiple test methods(if its really needed) or use anyInteger sort of stuff based on my needs.

Getting number of calls to a mock

Assume I want to test code like this:
class ClassToTest
// UsedClass1 contains a method UsedClass2 thisMethod() {}
UsedClass1 foo;
void aMethod()
{
int max = new Random().nextInt(100);
for(i = 0; i < max; i++)
{
foo.thisMethod().thatMethod();
}
}
}
If I have a test like this:
ClassToTest test;
UsedClass1 uc1;
UsedClass2 uc2;
#Test
public void thingToTest() {
test = new ClassToTest();
uc1 = mock(UsedClass1.class);
uc2 = mock(UsedClass2.class);
when(uc1.thisMethod()).thenReturn(uc2);
when(uc2.thatMethod()).thenReturn(true);
test.aMethod();
// I would like to do this
verifyEquals(callsTo(uc1.thisMethod()), callsTo(uc2.thatMethod()));
}
How can I get the number of calls to uc1.thisMethod() and uc2.thatMethod() so I can check they were both called the same number of times?
You can do something like this:
YourService serviceMock = Mockito.mock(YourService.class);
// code using YourService
// details of all invocations including methods and arguments
Collection<Invocation> invocations = Mockito.mockingDetails(serviceMock).getInvocations();
// just a number of calls of any mock's methods
int numberOfCalls = invocations.size();
If you want only the invocations of certain method/param combination you, you can do so with
int specificMethodCall = Mockito.mockingDetails(serviceMock.myMethod(myParam)).getInvocations()
You could stub your methods, and increment a counter, like this:
final AtomicInteger countCall1 = new AtomicInteger();
Mockito.doAnswer(new Answer<UsedClass2>() {
#Override
public UsedClass2 answer(InvocationOnMock invocation) throws Throwable {
countCall1.incrementAndGet();
return uc2;
}
}).when(uc1).thisMethod();
If you know the number of times a method is suppoed to be called you can use the times() method of Mockito
//for example if had to be called 3 times
verify(uc1, times(3)).thisMethod();
verify(uc2, times(3)).thatMethod();
However, I now see that you call the method a random number of times, so this probably isn't the best answer unless you stub out the random number generator to always return an expected value.
You can use a custom VerificationMode to count the invocations, here you go:
public class InvocationCounter {
public static <T> T countInvocations(T mock, AtomicInteger count) {
return Mockito.verify(mock, new Counter(count));
}
private InvocationCounter(){}
private static class Counter implements VerificationInOrderMode, VerificationMode {
private final AtomicInteger count;
private Counter(AtomicInteger count) {
this.count = count;
}
public void verify(VerificationData data) {
count.set(data.getAllInvocations().size());
}
public void verifyInOrder(VerificationDataInOrder data) {
count.set(data.getAllInvocations().size());
}
#Override
public VerificationMode description(String description) {
return VerificationModeFactory.description(this, description);
}
}
}
And then use it like this (works also with void return types):
#Mock
private Function<String, Integer> callable;
AtomicInteger count= new AtomicInteger(); //here is the actual invocation count stored
countInvocations(callable,count).apply( anyString());
assertThat(count.get(),is(2));

JUnit Tests: object not recreated between parameterized tests

I'm trying to test implementations of a Collections interface using JUnit4 Parameterized tests. My test class has two tests:
#RunWith(Parameterized.class)
public class CollectionsTest {
private Collection<String> col;
private Collection<String> other;
public CollectionsTest(Collection<String> c, Collection<String> other) {
this.col = c;
this.other = other;
}
#Parameterized.Parameters
public static java.util.Collection<Object[]> tokenStreams() {
return (java.util.Collection<Object[]>) Arrays.asList(new Object[][] {
{ new DSLinkedList<String>(), new DSLinkedList<String>() } });
}
#Test
public final void isEmpty() {
assertTrue(col.getClass().getName() + ".isEmpty() should return true when collection contains no elements", col.isEmpty());
col.add("Stringthing");
assertFalse(col.getClass().getName() + ".isEmpty() should return false when collection contains elements", col.isEmpty());
}
#Test
public final void size() {
assertEquals(col.getClass().getName() + ".size() should be 0 for an empty collection.", 0, col.size());
col.add("String");
assertEquals(col.getClass().getName() + ".size() should be 1 for a collection with one element.", 1, col.size());
}
}
The second test (size()) always fails: at the time of the first assertion, col contains a single element stringThing, because I inserted an element in the isEmpty() test.
How do I clean the parameterized objects between tests?
If I wasn't using a parameterized test, I'd use #Before with a setup() method: should I be using reflection and a setup method here to recreate the col and other objects? (I haven't done this because I don't know which Collection implementation each test is running beforehand: if I have to manually write code using reflection to determine this, what's the point of Parameterized tests?)
My understanding is that the Parameterized tests call the constructor before each test, which should 'reset' my objects cleanly: why is this not the case?
Parameterized creates a new CollectionsTest object before each tests and calls the constructor, but it passes the same DSLinkedList objects each time, tokenStreams() is called only once for whole testcase. You should clean the lists in the constructor yourself.
In Java 8 this can be done fairly cleanly using lambda expressions and the utility class java.util.function.Supplier. Instead of providing an instance of the parameter type, you provide a lambda which supplies a new instance each time it is evaluated. JUnit passes the lambda to the constructor for each test case, where a new instance is created with a call to get().
#RunWith(Parameterized.class)
public class CollectionsTest {
private Collection<String> col;
private Collection<String> other;
public CollectionsTest(Supplier<Collection<String>> c, Supplier<Collection<String>> other) {
this.col = c.get();
this.other = other.get();
}
#Parameterized.Parameters
public static java.util.Collection<Object[]> tokenStreams() {
Supplier<Collection<String>> c1 = () -> new DSLinkedList<String>();
Supplier<Collection<String>> c2 = () -> new DSLinkedList<String>();
return Arrays.asList(new Object[][] { { c1, c2 } });
}
#Test
public final void isEmpty() {
assertTrue(col.getClass().getName() + ".isEmpty() should return true when collection contains no elements", col.isEmpty());
col.add("Stringthing");
assertFalse(col.getClass().getName() + ".isEmpty() should return false when collection contains elements", col.isEmpty());
}
#Test
public final void size() {
assertEquals(col.getClass().getName() + ".size() should be 0 for an empty collection.", 0, col.size());
col.add("String");
assertEquals(col.getClass().getName() + ".size() should be 1 for a collection with one element.", 1, col.size());
}
This is a late response. But I had the same dilemma and I solved it like this:
#RunWith(Parameterized.class)
public class CollectionsTest {
private Collection<String> col;
private Collection<String> other;
private Class<Collection> source1;
private Class<Collection> source2;
public CollectionsTest(Class<Collection> first, Class<Collection> second) {
this.source1 = first;
this.source2 = second;
}
#Parameters
public static Collection<Object[]> instancesToTest() {
return Arrays.asList(new Object[][] {
{ DSLinkedList.class, DSLinkedList.class },
{ OtherCollection.class, MyCollection.class }
});
}
#Before
public void setUp() throws Exception {
this.col = source1.newInstance();
this.other = source2.newInstance();
}
. . .
This approach works as long as your classes have a default constructor (no arguments).
The #Before setup() method gets called before each test and creates a new instance for your objects.
To use non-default constructors yo can use getConstructor() to choose which constructor you want:
this.col = source1.getConstructor(String.class).newInstance("Hello object");
You can create new objects within your tests too, using the same technique (e.g. Collection<String> c1 = source1.newInstance()), those tests have to throw an Exception (you will get a compile time error if they don't)
Well, you are changing the member variable value though. So, are you expecting the constructor to be called before each test? Also, as per the documentation of Parameterized. Your Test class instance would be provided with the data values in the #Parameters method. It isnt every test it is the instance of the class.
Parameterized

Access a List in JUnit Test Case

I have this ParkingLot.java
public class ParkingLot {
private final int size;
private Car[] slots = null;
List<String> list = new ArrayList<String>();
public ParkingLot(int size) {
this.size = size;
this.slots = new Car[size];
}
public List licenseWithAParticularColour(String colour) {
for (int i = 0; i < slots.length; i++) {
if (slots[i].getColour() == colour) {
System.out.println(slots[i].getLicense());
list.add(slots[i].getLicense());
return list;
}
}
return null;
}
}
I have created a ParkingLotTest.java as follows
public class ParkingLotTest {
private Car car1;
private Car car2;
private Car car3;
private Ticket ticket1;
private Ticket ticket2;
private Ticket ticket3;
private ParkingLot parkingLot;
private List<String> list = new ArrayList<String>();
#Before
public void intializeTestEnvironment() throws Exception {
this.car1 = new Car("1234", "White");
this.car2 = new Car("4567", "Black");
this.car3 = new Car("0000", "Red");
this.parkingLot = new ParkingLot(2);
this.ticket1 = parkingLot.park(car1);
this.ticket2 = parkingLot.park(car2);
this.ticket3 = parkingLot.park(car3);
this.list = parkingLot.list;
}
#Test
public void shouldGetLicensesWithAParticularColour() throws Exception {
assertEquals(, parkingLot.licenseWithAParticularColour("White"));
}
}
In the above Test Case, I want to check that the List is filled with the correct Licenses.
1. How do i create a field in the ParkingLotTest.java so that the List in the first class is same as list in the second class file.
First, I don't think you need a list on ParkingLot so your question actually doesn't make much sense :)
Second, just set up the expected result in each test method:
public class ParkingLotTest {
//...
#Test
public void shouldGetLicensesWithAParticularColour() throws Exception {
List<Car> expected = new ArrayList<Car>();
expected.add(...);
assertEquals(expected, parkingLot.licenseWithAParticularColour("White"));
}
}
And don't forget to also test unexpected values or special cases. For example:
#Test
public void shouldNotGetLicensesWithANullColour() throws Exception {
...
assertEquals(expected, parkingLot.licenseWithAParticularColour(null));
}
#Test
public void shouldNotGetLicensesWithAnUnknownColour() throws Exception {
...
assertEquals(expected, parkingLot.licenseWithAParticularColour("unknown"));
}
Some additional remarks:
I wouldn't use a Car[] for the slots but a List<Car>.
You don't really need the List<String> list in ParkingLot (and the current implementation of licenseWithAParticularColour is buggy).
I would use an Enum for the color.
However you want?
That's somewhat in jest, but however you normally build a List will do just fine - as long as it's consistent with what you want your tested interface list to be.
For this particular case, I'd recommend building a List<Car> as your test reference, then visiting each Car and parking it. You can then build the licenses list from that reference list, and compare it to the parking lot one. Just make sure your iteration direction is correct.
BTW, from what I see, I don't think things work the way they're supposed to work - good thing you're testing it.
Pascal's Answer worked for me.
#Pascal Again, I made this function:
public List getSlotNumbersWithAParticularColour(String colour) {
List<Integer> listOfTicketsWithAColour = new ArrayList<Integer>();
for (int i = 0; i < slots.length;) {
if (slots[i].getColour() == colour) {
listOfTicketsWithAColour.add(i);
}
return listOfTicketsWithAColour;
}
return null;
}
The fault is not in the for loop, adding an i++ is "dead-code" acc to Eclipse. Adding the i++ doesnt cause any difference.
And the corresponding test-case:
public void getSlotNumbersWithAGivenColour() throws Exception {
List<String> expected = new ArrayList<String>();
expected.add("0");
expected.add("3");
assertEquals(expected, parkingLot.getSlotNumbersWithAParticularColour("White"));
}
The test fails. The function only returns 0, instead of 0,3. Any idea why?

Categories