简体   繁体   中英

Unit-testing adding to a collection without contains() method

Consider this class:

public class Customer {

    private final List<Rental> rentals;

    public Customer() {
        this.rentals = new ArrayList<>();
    }

    public void addRental(Rental rental) {
        if (rental != null) {
            this.rentals.add(rental);
        }
    }

    public BigDecimal sumRentals() {
        return rentals.stream()
                .map(r -> r.getPrice())
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
}

I want to create a unit test on the addRental() method, yet I don't want to publish a getter to the rental member, nor do I plan on publishing a consists() method and writing it just for the sake of tests seems a bad practise.

So the question is: how do I go about testing addRental() ? Do I make use of the sumRentals() method, even if the test is indirect (I would be checking if the sum of elements changed correctly and not if the element was actually added to the collection)? Do I forget about testing addRental() altogether since it's so trivial? What if it wasn't though and there was some more logic to it?

Unit testing should generally test the behavior of your classes, not the implementation. If the only visible effect of addRental() is via sumRentals() , that's the right method to test against.

Say tomorrow you decide to modify your implementation:

public class Customer {

    private BigDecimal rentalSum = BigDecimal.ZERO;

    public void addRental(Rental rental) {
        rentalSum = rentalSum.add(rental.getPrice());
    }

    public BigDecimal sumRentals() {
        return rentalSum;
    }
}

Your unit test shouldn't have to know that the implementation changed. If you test against sumRentals() , it won't.

I would go for a guard test or with a delta test:

Guard Test:

// arrange
Customer customer = new Customer();
assertThat(customer.sumRentals() == BigDecimal.ZERO);

// act
customer.addRental(new Rental());

// assert
assertThat(customer.sumRentals() == BigDecial.valueOf(1));

Delta Test:

// arrange
Customer customer = new Customer();
initialSum = customer.sumRentals();

// act
customer.addRental(new Rental());

// assert
assertThat(customer.sumRentals() == initialSum + 1);

Or both.. using the available api all the time. The same as with testing the workings of a list.. you test the add , but you check with the size .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM