Reputation: 49
Hello so I have been trying to figure this problem out for a bit now and I googled. I have found posts on here with the same problem, but they didn't really help me.
In my JUnit test the call for PaymentBatchProcessor checkProcessor = new PaymentBatchProcessor<>();
causes "Cannot infer type arguments for PaymentBatchProcessor<>"
I just learned about Generics and that's why I'm having such a hard time implementig it. I understand the general concept of Generics.
public class PaymentBatchProcessor <T extends Payment> {
// Variables
private T payment;
List <T> listOfPayments;
// Constructor
public PaymentBatchProcessor(T payment) {
this.payment = payment;
this.listOfPayments = new ArrayList<>();
}
// add method
public void add(T payment) {
this.listOfPayments.add(payment);
}
// getMax method
public double getMax () {
// Placeholder
double maxAmount = 0.0;
for( T payment : listOfPayments) {
// displaying each payment to console
System.out.println(payment);
// If current payment is more then current maxAmount
// assign new highest amount
if(payment.getAmount() > maxAmount) {
maxAmount = payment.getAmount();
}
}
// Return highest amount
return maxAmount;
}// END OF getMax()
// getTotal method
public double getTotal() {
// Accumulator
double total = 0.0;
// Add each payment amount to total
for( T payment : listOfPayments) {
total += payment.getAmount();
}
return total;
}// END OF getTotal()
// getSize method
public int getSize() {
// Return size of list
return listOfPayments.size();
}
}// END OF PAYMENTBATCHPROCESSOR
//Interface
public interface Payment {
public double getAmount();
public void setAmount(double amount);
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Check class
public class Check implements Payment{
// Variable
private double amount;
// Constructor
public Check (double amount) {
this.amount = amount;
}
// Getter and Setter
public double getAmount() {
return this.amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
}// END OF CHECK
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public class IOU implements Payment {
// Variable
private double amount;
// Constructor
public IOU (double amount) {
this.amount = amount;
}
// Getter and Setter
public double getAmount() {
return this.amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
}// END OF IOU
}
// +++++++++++++ PROBLEM AREA +++++++++++++++++++++++++++++++++++++++++++++++++
import static org.junit.Assert.*;
import java.util.ArrayList;
import org.junit.Test;
public class TestGenerics
{
@Test
public void testProcessorAsCheck()
{
PaymentBatchProcessor<Check> checkProcessor = new PaymentBatchProcessor<>();
checkProcessor.add( new Check(5.00) );
checkProcessor.add (new Check(10.00) );
assertEquals(15, checkProcessor.getTotal(), 2);
assertEquals(10, checkProcessor.getMax(), 2);
}
@Test
public void testProcessorAsIOU()
{
PaymentBatchProcessor<IOU> processor = new PaymentBatchProcessor<>();
processor.add( new IOU(22.54) );
processor.add( new IOU(22.55) );
assertEquals(45.09, processor.getTotal(), 2);
assertEquals(22.55, processor.getMax(), 2);
}
@Test
public void testProcessorAsPayment()
{
Payment iou = new IOU(11.22);
Payment iou2 = new Check(22.11);
PaymentBatchProcessor<Payment> processor = new PaymentBatchProcessor<>();
processor.add(iou);
processor.add(iou2);
assertEquals(33.33, processor.getTotal(), 2);
assertEquals(22.11, processor.getMax(), 2);
}
@Test
public void testProcessorAsPaymentWithEmptyList()
{
PaymentBatchProcessor<Payment> processor = new PaymentBatchProcessor<>();
assertEquals(0, processor.getTotal(), 2);
assertNull(null, processor.getMax());
}
@Test
public void testProcessorHelperAsPayment()
{
ArrayList<Payment> list = new ArrayList<Payment>();
list.add( new Check(10.00) );
list.add( new Check(5.00) );
list.add( new IOU(1.00) );
assertEquals(10, PaymentProcessorHelper.<Payment> getMax(list).getAmount(), 2);
assertEquals(16, PaymentProcessorHelper.<Payment> getSum(list), 2);
}
@Test
public void testProcessorHelperAsPaymentEmptyList()
{
ArrayList<Payment> list = new ArrayList<Payment>();
assertNull(PaymentProcessorHelper.<Payment> getMax(list));
assertEquals(0, PaymentProcessorHelper.<Payment> getSum(list), 2);
}
@Test
public void testProcessorHelperAsCheck()
{
ArrayList<Check> list = new ArrayList<Check>();
list.add( new Check(10.00) );
list.add( new Check(5.00) );
assertEquals(10, PaymentProcessorHelper.<Check> getMax(list).getAmount(), 2);
assertEquals(15, PaymentProcessorHelper.<Check> getSum(list), 2);
}
@Test
public void testProcessorHelperAsIOU()
{
ArrayList<IOU> list = new ArrayList<IOU>();
list.add( new IOU(11.22) );
list.add( new IOU(22.11) );
assertEquals(22.11, PaymentProcessorHelper.<IOU> getMax(list).getAmount(), 2);
assertEquals(33.11, PaymentProcessorHelper.<IOU> getSum(list), 2);
}
}
Upvotes: 1
Views: 9808
Reputation: 1915
For PaymentBatchProcessor
you have defined a constructor that takes a Payment
as an argument, but in the tests you try to use a no-arguments constructor new PaymentBatchProcessor<>()
, which doesn't exist.
You either need to define a no-arguments constructor or provide an argument to the constructors in your tests.
And I'm also trying to make getMax and getTotal a generic method
Based on the code in your question I don't really understand why you would want to do that.
I tried making them public static < T >
I think you have misunderstood something about generics (and also the static
modifier) here.
It doesn't look like getMax
and getTotal
should ever return anything other than double
and they don't take any arguments so there is no issue of handling different types of inputs.
And you can't make those methods static
because they operate on instance variables (not class variables).
Upvotes: 1