Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JUnit Test Case via Private Method in Dijkstra Algorithm

I'm trying to figure out the best way to implement a test case for a class exercise. My class exercise provides the known bug and with this I should write a test case for it to fail, and thus find the bug. It involved using the Dijkstra Algorithm.

This is the correct version of the provided code:

private int getNodeWithMinimumDistanceFromUnsettled()
{
    int min;
    int node = 0;

    Iterator<Integer> iterator = unsettled.iterator();
    node = iterator.next();
    min = distances[node];
    for (int i = 1; i <= number_of_nodes; i++)
    {
        if (unsettled.contains(i))
        {
            if (distances[i] <= min)
            {
                min = distances[i];
                node = i;
            }
        }
    }
    return node;
}

The known bug in a separate version is as follows:

if (unsettled.contains(i))
        {
            if (distances[i] > min)
            {
                min = distances[i];
                node = i;
            }
        }

and here is the JUnit Test case I'm using to find it. I'm trying to access this method with Java Reflection and then try to assert whether the node returned is equal to the node is actually the larger distance.

Here is my test case:

int[][] adjacency = { { 0, 0, 0, 0, 0 },
                          { 0, 0, 9, 10, 0 },
                          { 0, 9, 0, 0, 0 },
                          { 0, 5, 4, 0, 2 },
                          { 0, 5, 4, 3, 0 },
                                             }; 
 Dijkstra d1 = new Dijkstra(4);
 d1.dijkstra_algorithm(adjacency, 1);



    /*
    try {

    nodeMethod =   Dijkstra.class.getDeclaredMethod("getNodeWithMinimumDistanceFromUnsettled");

    } catch (NoSuchMethodException e) {
        System.out.println(e.getMessage());
    }

    nodeMethod.setAccessible(true);

    try {   
            node = (int) nodeMethod.invoke(d1);
            System.out.println("min node is: " + node);     
    } catch (IllegalAccessException | InvocationTargetException e) {
            System.out.println(e.getMessage());
    }

    assertEquals(node, 0); 
    */

When I run the test, it doesn't seem to do anything as I get no output. I feel like I'm overthinking this. Is there an easier way to find this bug without using java reflection?

like image 558
devindj6932 Avatar asked Apr 30 '15 11:04

devindj6932


1 Answers

Since you tagged this with junit, I'll answer in kind. You should not unit test private methods, you should test the public (or protected) method that uses the private method. So:

@Test
public void testDijkstra()
{
    Dijkstra d1 = new Dijkstra(4);
    assertThat( "should be <what you expect>" , 
                d1.dijkstra_algorithm(adjacency, 1) , 
                equalTo( 42 /* <-- expected result goes here*/ ) );
}

(Purists will probably bash me for it, but when working on legacy code I routinely change private methods to protected to enable easy unit test coverage before refactoring, so that - unpure - idea is hereby passed on to you).

Cheers,

like image 120
Anders R. Bystrup Avatar answered Nov 15 '22 06:11

Anders R. Bystrup