How to test array for equality with multiple input data

Tags: , ,



I have been searching on any documentation if this is possible with parameterized junit4 testing.

Basically what I have is two classes, GameEntry and Scoreboard:

public class GameEntry{
    private String name;
    private int score;

    // Constructor and Getters...
}

public class Scoreboard{
    private int numEntries = 0;
    private GameEntry[] board;

    // Constructor
    public Scoreboard(int capacity){
        board = new GameEntry[capacity];
    }

    // Add method - Only if entry is higher than current entries
    public void add(GameEntry e){
        // Code here...         
    }

    // Remove method

    // Reset method
}

I’ve read about parameterized testing where you return an array of different input data Passing arrays to Parameterized JUnit, but it is not quite what I would like to do. I’m interested in running 10 different tests where I would create an input text file with gameEntries name, score values, and another text file for expected values for name, and score. I would like to keep all data out of the testing class in case I want to change the data later on. After the input, and expected files have been parsed, then I would just use Assert.assertArrayEquals( expectedResult, result ) to compare the array.

I shouldn’t have any problems doing this without a parameterized Junit test, but then if one test fails the whole test would fail. I guess I could keep a counter to track input. I would like to write just one test to avoid DRY. Is this possible with Junit or other testing framework?

Answer

JUnit 5 has the concept of “dynamic tests”, which allows you to generate test cases at runtime.

Have a look at this example (borrowed from a JUnit 5 workshop):

class PrimeNumbersTest {

    @TestFactory
    Stream<DynamicTest> test_first_1000_prime_numbers() throws Exception {
        return primes().mapToObj(prime -> DynamicTest.dynamicTest(
                // Test case name.
                "Prime: " + prime,
                // Test case content.
                () -> assertTrue(PrimeNumbers.isPrime(prime))));
    }

    private LongStream primes() throws Exception {
        Path primesTxt = Paths.get(getClass().getResource("/primes.txt").toURI());
        return Files.lines(primesTxt).mapToLong(Long::parseLong);
    }

}

test_first_1000_prime_numbers() uses @TestFactory to create a test case for each prime number returned by primes(), which loads them from the external resource primes-1000.txt. For example, IntelliJ displays this as follows:

enter image description here

So, you could dynamically create a test case for each of your setups. This keeps the test data out of the test class and only those tests will fail that contain failed assertions.

Have a look at the user guide or this excellent blog post for further information, but bear in mind that JUnit 5 is still under development.



Source: stackoverflow