Access a List in JUnit Test Case - java

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?

Related

Adding custom class objects to list showing ambiguity

This is a sample test code I wrote to ensure what I know is right
class Form {
List<Sample> samples;
List<Sample> sampleList;
public List<Sample> getSamples() {
return samples;
}
public void setSamples(List<Sample> samples) {
this.samples = samples;
}
public List<Sample> getSampleList() {
return sampleList;
}
public void setSampleList(List<Sample> sampleList) {
this.sampleList = sampleList;
}
void setInitialData() {
this.samples = new ArrayList<Sample>();
this.sampleList = new ArrayList<Sample>();
}
}
class Sample {
}
public class ListAddingAmbiguity {
public static void main(String[] args) {
Form form = new Form();
form.setInitialData();
Sample sample = new Sample();
form.getSamples().add(sample);
form.getSampleList().add(sample);
System.out.println(form.getSamples().size());
System.out.println(form.getSampleList().size());
}
}
The output coming is
1
1
And it is correct, samples and sampleList are two different references pointing to two different memory locations, so adding to samples won't change the size of sampleList.
But in my project code it is different, this is my Form class
public class InvoiceForm extends BaseActionForm {
private List<ProductTO> products;
private List<ProductTO> productList;
// getters and setters
}
This is the code in my Action class
private void setProductsToInvoice(InvoiceForm invoiceForm) throws Exception {
if(invoiceForm.getProducts() != null && !invoiceForm.getProducts().isEmpty()){
ProductTO productTO = new ProductTO();//ProductEntryHandler.getInstance().prepareProductsForInvoice();
invoiceForm.getProducts().add(productTO);
invoiceForm.getProductList().add(productTO);
}else {
List<ProductTO> productTOs = new ArrayList<ProductTO>();
productTOs.add(ProductEntryHandler.getInstance().prepareProductsForInvoice());
invoiceForm.setProducts(productTOs);
invoiceForm.setProductList(productTOs);
}
}
Both the products and productList are having a size of 1 initially, so in the above code if block will execute. The commented portion is the earlier code. Even if it is the new code ProductTO productTO = new ProductTO(); or the old code ProductTO productTO = ProductEntryHandler.getInstance().prepareProductsForInvoice(); the problem is the same.
Like I said when execution comes to the method both the lists are having a size of 1. When the line invoiceForm.getProducts().add(productTO); is executed the size of products and productList size becomes 2, which is in conflict with my test code. Now when the nest line invoiceForm.getProductList().add(productTO); is executed both the list size is becoming 3. I don't know why its happening, can anybody help?
The following code else case in setProductsToInvoice set both products and productList to the same list:
List<ProductTO> productTOs = new ArrayList<ProductTO>();
productTOs.add(ProductEntryHandler.getInstance().prepareProductsForInvoice());
invoiceForm.setProducts(productTOs);
invoiceForm.setProductList(productTOs);
The correct way, or at least the less incorrect way, is something like this:
ProductTO newProd =
ProductEntryHandler.getInstance().prepareProductsForInvoice());
invoiceForm.setProducts(new ArrayList<ProductTO>());
invoiceForm.getProducts().add(newProd);
invoiceForm.setProductList(new ArrayList<ProductTO>());
invoiceForm.getProductList().add(newProd);
I'd suggest an investigation to determine why there are two lists apparently being maintained in parallel in the first place. At first glance, it has a bit of a smell to it...

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.

I get null pointer exceptions on all my JUnits. in debug - Source not found

This JUnit test (and others) always fail because of a NullPointerException. When I debug, it returns an error of "Source not found" at line sq.setPlayers(players);
Below is a list of the class methods used and their dependencies. I can't imagine any reason why it wouldn't work.
public class SingleEliminationTest {
private Queue queue;
private Match currentMatch;
private SingleElimination sq;
public void setUp() {
queue = new Queue(4);
sq = new SingleElimination();
}
#Test
public void setPlayers()
{
ArrayList<String> players = new ArrayList<String>();
players.add("Max Atkins");
players.add("Hannah Marlow");
players.add("Liam Ross");
players.add("Chandlar Bruce");
sq.setPlayers(players);
assertEquals("Not enough players", queue.length(), 4);
}
public class SingleElimination implements IManager
{
private Queue queue;
private Match current;
public SingleElimination()
{
queue = new Queue(5);
}
/**
* Set the players or teams to use in the competition
* #param players the players or teams
*/
public void setPlayers(ArrayList<String> players)
{
for(String player : players)
{
queue.enQ(player);
}
}
public class Queue
{
Object[] queue;
int head;
int tail;
int length;
public Queue(int startSize)
{
queue = new Object[startSize];
head = tail = length = 0;
}
// Adds an Object to the back of the queue.
public void enQ(Object o)
{
if(length == queue.length)
{
//queue = new Object[queue.length * 2];
}
queue[tail++] = o;
length++;
if(tail == queue.length)
{
tail = 0;
}
}
You need to annotate the setup method otherwise it won't be run. I'm not very familiar with JUnit but I suspect #BeforeClass or #Before would do what you expect.
Use the #Before annotation if you want your setup method to run before each and every test (any method annotated with #Test), use the #BeforeClass annotation if you want your setup method run once and only once.
You need to annotate your setUp method with #Before. It's not being run.

Odd Null Pointer Exception

I'll get right to it.
So I have code that gets a Null Pointer Exception. I've tried looking up what causes it and how to fix it, but that's why I'm confused with this particular code. It was working just fine earlier today and now its throwing the exception. Any help? I'm probably just overlooking something silly but it's quite frustrating. Code follows:
import java.util.*;
import java.io.*;
public class ShopMain<T> {
List<T> stock;
public void Shop() { stock = new LinkedList<T>(); }
public T buy() { return stock.remove(0); }
void sell(T item) { stock.add(item); }
void buy(int n, Collection<? super T>items) {
for (T e : stock.subList(0, n)) {
items.add(e);
}
for (int i=0; i<n; ++i) stock.remove(0);
}
void sell(Collection<? extends T> items) {
for (T e : items) {
stock.add(e);
}
}
public static void main (String[] args) {
ShopMain<Marker> paintballShop = new ShopMain<Marker>();
Console console = System.console();
System.out.println("1 - Test Suite");
String input = console.readLine("Please select the corresponding number to your choice.\n");
if(input.equals("1")){
Stack<Marker> stack = new Stack<Marker>();
Set<Marker> hashset = new HashSet<Marker>();
System.out.println("Test Suite : Tests List, Stack, HashSet");
paintballShop.sell(new Geo3());
paintballShop.sell(new Ego11());
paintballShop.buy();
paintballShop.buy(2, stack); //Stack use
paintballShop.sell(stack); //Stack use
paintballShop.buy(3, hashset); //HashSet
paintballShop.sell(hashset); //HashSet
System.out.println("Tests Complete");
}
}
}
Exception error occurring at runtime:
Exception in thread "main" java.lang.NullPointerException
at ShopMain.sell(ShopMain.java:14)
at ShopMain.main(ShopMain.java:39)
These last bits are just class 'placeholders' for the objects and their parent class.
public class Marker{}
public class Geo3 extends Marker{}
public class Ego11 extends Marker{}
Thanks again for any help.
That's because your List List<T> stock; is still uninitialized. You need to initialize it for you to be able to add, remove elements to/from it. By default, its null and thus, when you try to call a method on it, you get the NullPointerException.
This happens because you don't have a constructor at all. Shop() is not the constructor of your class. A constructor has the same name as the class, and thus you need to have your constructor like this
public ShopMain() { stock = new LinkedList<T>(); }
Incase, Shop() is a valid method, then you need to call this method so that your list is initialized and only then call the other methods.
paintballShop.Shop(); // Call this method to init your list.
change to constructor..
public ShopMain() { stock = new LinkedList<T>(); }
You probably need to change:
public void Shop() { stock = new LinkedList<T>(); }
//doesn't look a method name, may be this is what you missed
to
public ShopMain() { stock = new LinkedList<T>(); }
You don't have a constructor for ShopMain that initializes your List.
Add this:
ShopMain() {
stock<T> = new ArrayList<T>();
}
Basically it comes do to the fact that stock is never initialised. I imagine that the class use to be called Shop
You could change...
public class ShopMain<T> {
List<T> stock;
public void Shop() {
stock = new LinkedList<T>();
}
To...
public class ShopMain<T> {
List<T> stock;
public ShopMain() {
stock = new LinkedList<T>();
}
Which will initialise the List when the class is constructored...

Converting an array of one type to an array of a subtype

I want to convert an array from one type to another. As shown below, I loop over all objects in the first array and cast them to the 2nd array type.
But is this the best way to do it? Is there a way that doesn't require looping and casting each item?
public MySubtype[] convertType(MyObject[] myObjectArray){
MySubtype[] subtypeArray = new MySubtype[myObjectArray.length];
for(int x=0; x < myObjectArray.length; x++){
subtypeArray[x] = (MySubtype)myObjectArray[x];
}
return subtypeArray;
}
You should be able to use something like this:
Arrays.copyOf(myObjectArray, myObjectArray.length, MySubtype[].class);
However this may just be looping and casting under the hood anyway.
See here.
I would suggest working with List instead of Array if possible.
Here is how to do it:
public class MainTest {
class Employee {
private int id;
public Employee(int id) {
super();
this.id = id;
}
}
class TechEmployee extends Employee{
public TechEmployee(int id) {
super(id);
}
}
public static void main(String[] args) {
MainTest test = new MainTest();
test.runTest();
}
private void runTest(){
TechEmployee[] temps = new TechEmployee[3];
temps[0] = new TechEmployee(0);
temps[1] = new TechEmployee(1);
temps[2] = new TechEmployee(2);
Employee[] emps = Arrays.copyOf(temps, temps.length, Employee[].class);
System.out.println(Arrays.toString(emps));
}
}
Just remember you cannot do it the other way around, i.e. you cannot convert Employee[] to a TechEmployee[].
Something like this is possible if you fancy
public MySubtype[] convertType(MyObject[] myObjectArray){
MySubtype[] subtypeArray = new MySubtype[myObjectArray.length];
List<MyObject> subs = Arrays.asList(myObjectArray);
return subs.toArray(subtypeArray);
}

Categories