简体   繁体   中英

How does Java's hierarchical algorithm work?

This is what I intend to do I am facing problems when designing Junit test cases for boundary value analysis. The first class is the class that executes logic sorting based on hierarchy. The program does not behave properly when assertEquals is being used. It kept on repeating what the previous assertEquals has done. Hence, in the end, any further evaluations will be deemed useless.

public class AssignCharges {
    RandomGeneratorClass rgc = new RandomGeneratorClass();

    // To test for cases less than 0
    public double getCharges(int distance, int weight) {
    // declaring the variable to be fit into the given situation
    double charges = 0;

    if(weight < 0 || distance < 0)
        throw new IllegalArgumentException("Values cannot be negative.");

    //  Testing for valid first boundary values
    //  @ <300g, <10km, RM 5
    else if(weight > 0 && weight < 300){
        charges = 5;
    }
    //  Testing for valid second boundary values @ 300-1000g
    else if(weight >= 300 && weight < 1000){
    //  @ distance < 10km, RM 8
        if(distance > 0 && distance < 10)
            charges = 8;
    //  @ 10 < distance < 30, RM 10
        else if(distance >= 10 && distance < 30)
            charges = 10;
    //  @ distance >= 30, RM 20
        else
            charges = 20;
    }
    //  Testing for valid third boundary values @ 1001-3000 g
    else if(weight >= 1000 && weight <3000){
    //  @ < 10km, RM 8
        if(distance > 0 && distance < 10)
            charges = 8;
    //  @ 10 < distance < 30, RM 12
        else if(distance >= 10 && distance < 30)
            charges = 12;
    //  @ distance > 30, RM 30
        else
            charges = 30;
    }

    //  Testing for valid fourth boundary values @ 3001-5000g
    else if(weight >= 3000 && weight < 5000){
    //  @ < 10km, RM 10
        if(distance > 0 && distance < 10)
            charges = 10;
    //  @ 10 < distance < 30, RM 15
        else if(distance >= 10 && distance < 30)
            charges = 15;
    //  @ distance > 30, RM 40
        else
            charges = 40;
    }

    //  Testing for valid fifth boundary values @ >5000g
    else if(weight >= 5000){
    //  @ < 10km, RM 15
        if(distance > 0 && distance < 10)
            charges = 15;
    //  @ 10 < distance < 30, RM 20
        else if(distance >= 10 && distance < 30)
            charges = 20;
    //  @ distance > 30, RM 50
        else
            charges = 50;
    }

    //  Testing for invalid negative boundary values
    //  The else is sufficient as the only invalid values = negative values
    else if(weight == 0 && distance == 0)
        charges = 0;

    //  replies the amount of corresponding charges
    return charges;
}

This will be the Junit code:

public class AssignChargesTest {
    @Test
    public void testAssignWeightDistanceInvalidBoundary(){
        AssignCharges ac = new AssignCharges();
        double charges;

        //  invalid boundary
        charges = ac.getCharges(0, 0);
        assertEquals(0, charges, 0);
    }

    @Test
    public void testAssignWeightDistanceFirstBoundary(){
        AssignCharges ac = new AssignCharges();
        double charges;

        //  first boundary
        charges = ac.getCharges(299, 5);
        assertEquals(5, charges, 0);
    }

    @Test
    public void testAssignWeightDistanceSecondBoundary(){
        AssignCharges ac = new AssignCharges();
        double charges;

        //  second boundary
        charges = ac.getCharges(999, 5);
        assertEquals(8, charges, 0);
        charges = ac.getCharges(999, 20);
        assertEquals(10, charges, 0);
        charges = ac.getCharges(999, 40);
        assertEquals(20, charges, 0);
    }

    @Test
    public void testAssignWeightDistanceThirdBoundary(){
        AssignCharges ac = new AssignCharges();
        double charges;

        //  third boundary
        charges = ac.getCharges(2999, 5);
        assertEquals(8, charges, 0);
        charges = ac.getCharges(2999, 20);
        assertEquals(12, charges, 0);
        charges = ac.getCharges(2999, 40);
        assertEquals(30, charges, 0);
    }

    @Test
    public void testAssignWeightDistanceFourthBoundary(){
        AssignCharges ac = new AssignCharges();
        double charges;

        //  fourth boundary
        charges = ac.getCharges(4999, 5);
        assertEquals(10, charges, 0);
        charges = ac.getCharges(4999, 20);
        assertEquals(15, charges, 0);
        charges = ac.getCharges(4999, 40);
        assertEquals(40, charges, 0);
    }

    @Test
    public void testAssignWeightDistanceFifthBoundary(){
        AssignCharges ac = new AssignCharges();
        double charges;

        //  fifth boundary
        charges = ac.getCharges(5001, 5);
        assertEquals(15, charges, 0);
        charges = ac.getCharges(5001, 20);
        assertEquals(20, charges, 0);
        charges = ac.getCharges(5001, 40);
        assertEquals(50, charges, 0);
    }


    @Test(expected = IllegalArgumentException.class)
    public void testIllegalArgumentException(){
        AssignCharges ac = new AssignCharges();
        double charges;

        //  invalid arguments list in terms of negative values:

        //  below boundary @ negative weight, negative distance
        charges = ac.getCharges(-5, -5);
        //  positive weight, negative distance
        charges = ac.getCharges(299, -5);
        charges = ac.getCharges(999, -5);
        charges = ac.getCharges(2999, -5);
        charges = ac.getCharges(4999, -5);
        charges = ac.getCharges(5001, -5);
        //  negative weight, positive distance
        charges = ac.getCharges(-1, 2);
        charges = ac.getCharges(-2, 12);
        charges = ac.getCharges(-3, 22);
        charges = ac.getCharges(-4, 32);
    }
}

JUnit is nothing but Java. Once one Java statement completes abruptly (eg throwing an exception), the subsequent ones aren't executed.

If you have a sequence of statements like this:

charges = ac.getCharges(-5, -5);
charges = ac.getCharges(-5, -5);
charges = ac.getCharges(-5, -5);
// ...

(I know they're all the same I just copied+pasted)

Once the first one fails, the others are redundant.

You need to do something like wrap the calls in a try/catch block, in order to allow execution to proceed beyond the failure:

try {
  ac.getCharges(-5, -5);
  fail();
} catch (IllegalArgumentException expected) {
}
try {
  ac.getCharges(-5, -5);
  fail();
} catch (IllegalArgumentException expected) {
}
// ...

so execution will continue.

This is obviously quite verbose. Instead, consider writing a method like this:

void assertGetChargesFails(int a, int b) {
  try {
    ac.getCharges(a, b);
    fail();
  } catch (IllegalArgumentException expected) {
  }
}

then invoke like:

assertGetChargesFails(-5, -5);
assertGetChargesFails(-5, -5);
assertGetChargesFails(-5, -5);

If you're using JUnit 4.15 or greater and Java 8, there is an assertThrows method which does this more nicely:

assertThrows(IllegalArgumentException.class, () -> ac.getChanges(-5, -5));
assertThrows(IllegalArgumentException.class, () -> ac.getChanges(-5, -5));

where each of the assertThrows lines will fail if the exception is not thrown.

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