#Need to write test for a method

39 messages · Page 1 of 1 (latest)

true crystal
#

am basically writing test cases for this method...and it's not able to detect one of the bugs.


   // MODIFIES: this
    // EFFECTS: if there is sufficient balance on the account
    //            - subtracts amount cents from balance
    //            - adds reward points and then
    //                - if eligible, adds cash back reward(s) to account and deducts corresponding reward points
    //            - returns true
    //          otherwise, returns false
    public boolean makePurchase(int amount) {
        return false;   // stub
    }

The bug that it's not able to test is the consistency of the method if it is called multiple times. I wrote a test where this thing is called three times, but it's still not enough

hollow knot
#

Well it looks like it's missing a lot wolfshrug but it looks pretty consistent to me

true crystal
#

I have implemented the method and it works fine, but I am wondering how should I write the test to test its consistency

#
public boolean makePurchase(int amount) {
        if (balance < amount) {
            return false;
        }
        balance -= amount;
        rewardPoints += amount * REWARD_POINTS_PER_CENT_CHARGED;
        if (rewardPoints >= POINTS_NEEDED_FOR_CASH_BACK) {
            balance += CASH_BACK_REWARD * (rewardPoints / POINTS_NEEDED_FOR_CASH_BACK);
            rewardPoints %= POINTS_NEEDED_FOR_CASH_BACK;
        }
        return true;
    }```
hollow knot
#

Wow line 13 is.. a lot

#

Anyway I'm not really sure what you mean by consistency. It should have the same affect given the same input

true crystal
#

this is basically the hint we got:

Methods should have consistent behavior, even if they are called multiple times in succession.

hollow knot
#

I think what they mean is that it won't break if you call it from the same instance twice

#

So in the tests you could just define the input of the second test to the same object as the first, and the expected output as usual

#

If the method modifies the object, I don't think it should return the same thing twice unless it can after the changes

true crystal
#

not sure what you mean...

hollow knot
#

So if the card only had $8 on it, calling makePurchase(500) twice would only return true the first time

true crystal
#

that didn't work

sturdy lintel
#

I took a look

true crystal
sturdy lintel
#

Holy fuck, add some white space, good grief...

@Test
    void testExtraPurchasesWithDifferentValues() {
        int previousPoints = foodServiceCard11.getRewardPoints();
        int previousBalance = foodServiceCard11.getBalance();
        int firstPurchase = (POINTS_NEEDED_FOR_CASH_BACK - foodServiceCard11.getRewardPoints())/REWARD_POINTS_PER_CENT_CHARGED - 1;
        int secondPurchase = POINTS_NEEDED_FOR_CASH_BACK;
        int thirdPurchase = POINTS_NEEDED_FOR_CASH_BACK * 2;
        int balanceAfterFirstPurchase = previousBalance - firstPurchase + CASH_BACK_REWARD * ((previousPoints + firstPurchase * REWARD_POINTS_PER_CENT_CHARGED) / POINTS_NEEDED_FOR_CASH_BACK);
        int rewardAfterFirstPurchase = (previousPoints + firstPurchase * REWARD_POINTS_PER_CENT_CHARGED) % POINTS_NEEDED_FOR_CASH_BACK;
        int balanceAfterSecondPurchase = previousBalance - (firstPurchase + secondPurchase) + CASH_BACK_REWARD * (previousPoints + (firstPurchase + secondPurchase) * REWARD_POINTS_PER_CENT_CHARGED / POINTS_NEEDED_FOR_CASH_BACK);
        int rewardAfterSecondPurchase = (previousPoints + firstPurchase * REWARD_POINTS_PER_CENT_CHARGED + secondPurchase * REWARD_POINTS_PER_CENT_CHARGED) % POINTS_NEEDED_FOR_CASH_BACK;
        int balanceAfterThirdPurchase = previousBalance - (firstPurchase + secondPurchase + thirdPurchase) + CASH_BACK_REWARD * (previousPoints + (firstPurchase + secondPurchase + thirdPurchase) * REWARD_POINTS_PER_CENT_CHARGED / POINTS_NEEDED_FOR_CASH_BACK);
        int rewardAfterThirdPurchase = (previousPoints + firstPurchase * REWARD_POINTS_PER_CENT_CHARGED + secondPurchase * REWARD_POINTS_PER_CENT_CHARGED + thirdPurchase * REWARD_POINTS_PER_CENT_CHARGED) % POINTS_NEEDED_FOR_CASH_BACK;
        assertTrue(foodServiceCard11.makePurchase(firstPurchase));
        assertEquals(balanceAfterFirstPurchase, foodServiceCard11.getBalance());
        assertEquals(rewardAfterFirstPurchase, foodServiceCard11.getRewardPoints());
        assertTrue(foodServiceCard11.makePurchase(secondPurchase));
        assertEquals(balanceAfterSecondPurchase, foodServiceCard11.getBalance());
        assertEquals(rewardAfterSecondPurchase, foodServiceCard11.getRewardPoints());
        assertTrue(foodServiceCard11.makePurchase(thirdPurchase));
        assertEquals(balanceAfterThirdPurchase, foodServiceCard11.getBalance());
        assertEquals(rewardAfterThirdPurchase, foodServiceCard11.getRewardPoints());
    }```
## unreadable lol
#

Ugh, forgot Discord Mobile doesn't do Java syntax highlighting

#

What exactly are you trying to test with that code???

true crystal
sturdy lintel
#

Can't you just call the same method on the same instance multiple times to check that it's consistent?

#

I don't think I'd ever test that in a test... I'd have mocks to eliminate any variability so it'd be assumed consistent every run

true crystal
#

I have tested that, but it didn't catch the bug it's supposed to catch. (idk what the bug exactly is). The test is supposed to catch that bug

sturdy lintel
#
for(int i=0; i<10000000000; i++){
    Call function and assert
}
#

Are they looking for an edge case? Function seems to simple for that

true crystal
#

Not sure...

sturdy lintel
#

Are you using floats at all? Maybe a rounding edge case

#

Could even be the case for ints

true crystal
#

no floats

sturdy lintel
#

I'd look for edge cases in int truncations then. For example 12/4 is 3, 11/4 is 2

true crystal
#

hmm ok I will think of a way to test that

winter cliff
#

Is there a problem when rewardpoints/points needed is 2x the points needed or more?

hollow knot
#

If rewardsPoints and POINTS_NEEDED_FOR_CASH_BACK are both ints, then it'll floor the result, so it might be that

#

I don't think you told us the data type of a lot of the variables here

#

I'm assuming balance is an integer representing cents

true crystal
#

ok found out what the issue was

#

I was testing the wrong method