简体   繁体   中英

JUnit test creating the same array instead of random one

I am creating a JUnit which is supposed to make each time an array of random size with random integers in it. Afterwards a copy of the array is made and the original array is inputed as a parameter in my mergesort array and gets sorted while the copy of the array gets sorted with the Arrays.sort() method. Then the two arrays are compared to see if they are the same.

Here is the code:

import java.util.Arrays;
import java.util.Random;
import static org.junit.Assert.assertArrayEquals;
import org.junit.Before;
import org.junit.Test;

public class Mergesort_3wayTest {

    private int[] toSort;
    private static int SIZE;
    private static int MAX;
    private static int tests = 20000;

    @Before
    public void setUp() throws Exception {
        Random generator = new Random();
        SIZE = generator.nextInt(30) + 1;
        MAX = generator.nextInt(30) + 1;
        toSort = new int[SIZE];
        for (int i = 0; i < toSort.length; i++) {
            toSort[i] = generator.nextInt(MAX);
        }
    }

    @Test
    public void itWorksRepeatably() {
        for (int i = 0; i < tests; i++) {
            System.out.println("1 - " + Arrays.toString(toSort));
            int[] sorted = new int[toSort.length];
            System.arraycopy(toSort, 0, sorted, 0, toSort.length);
            Arrays.sort(sorted);

            Mergesort_3way.mergesort(toSort);

            System.out.println("2 - " + Arrays.toString(toSort));

            assertArrayEquals(toSort, sorted);
        }
    }
}

I could clearly see from the println 's I inserted that only one array was created and the test was running constantly checking that one array but I thought it would create each time a random one which is clearly not the case.

So my question is why is only one array created which I guessed each time the assertArrayEquals(toSort, sorted) run it would the start over again.

I believe it has something to do with the global variables but I'm not quite sure...

You're looping inside your test method . The setup method will be called once before your test method, but it's not going to automatically be run at the start of each loop iteration. How would you expect it to be?

It should be creating a different random array each time you run the tests from scratch, but the 20000 iterations within that test run will all be dealing with the same array, as there's nothing to recreate it. If you want something to happen within your test method, you need to write that yourself.

The toSort Array is populated only once. In the setUp() method which is executed only once before the itWorksRepeatably method. Hence the itWorksRepeatably method uses the same array "tests" ie 20000 times.

You will need to move the logic that generates the array ( ie the code in the setUp method inside the for loop in the itWorksRepeatably method for you to see different arrays each time.

If you want this code to function the way you anticipate take the code in your setup function and make it into a new private method that is invoked at the start of each loop like so:

private void magic()
{
Random generator = new Random();
        SIZE = generator.nextInt(30) + 1;
        MAX = generator.nextInt(30) + 1;
        toSort = new int[SIZE];
        for (int i = 0; i < toSort.length; i++) {
            toSort[i] = generator.nextInt(MAX);
        }

}

Followed by:

@Test
    public void itWorksRepeatably() {
        for (int i = 0; i < tests; i++) {
           magic();  
           //rest of code  
}
}

Not entirely sure I understand... but in JUnit, the @Before methods are executed once before each @Test method. If you are looping within a @Test method, @Before isn't called. Since the @Before method is where you are re-initializing the array with random values, that's created only once per test.

Also, you cannot determine array creation by Arrays.toString(), simply because two arrays which have the same elements will display the same, even if they are two separate arrays.

You are creating a random array in your setUp method with @before annotation, this setup method will be called only once per test method. As you only have a single testmethod only one array is created and reused every time. Move the code to create random array from setup to for-loop inside your test method. Hope this helps

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