Bruce Zu
Bruce Zu

Reputation: 507

Junit @RunWith(Parameterized.class)

The differences between the following 2 cases are

a> The type of variable 'arr'. In the first case, its type is Integer[], while in the second case its type is int[].

b> We can see from where I marked as "// here" that in the case 1 it needs Integer[][][]. while in the case 2 it needs int[][].

Both of case 1 and case 2 work. So my question comes:

Why Junit require I return a 3-dimentional Integer array in the data() method in case 1 when the test data is a 1-dimentional Integer array. I expected it should be 2 - dimentional Integer array because in the case 2 I return a 2 - dimentional int array in the data() method and it is easy to understand it and it works. But when I tried to return 2-dimentional Integer array in the data() method in case 1 as

    @Parameterized.Parameters(name = "test with {index}")
    public static Iterable<Integer[]> data() {
      return Arrays.asList(new Integer[][]{ 
            {3, 1, 4, 6, 7, 9},  
            {9, 8, 7, 6, 5, 4},  
      }); 
    }

Junit reported "java.lang.IllegalArgumentException: wrong number of arguments". Please help me if you know the reason.

I searched Junit documents and many other pages without satisfied answer. Please help.My Junit version is 4.12.

case 1

@RunWith(Parameterized.class)
public class MyTest {
    @Parameterized.Parameters(name = "test with {index}")
    public static Iterable<Integer[][]> data() {
      //here:  My question is why it can not be Integer[][]
      return Arrays.asList(new Integer[][][]{ 
            {{3, 1, 4, 6, 7, 9}},  
            {{9, 8, 7, 6, 5, 4}},  
      }); 
    }

    private Integer[] arr;

    public MyTest(Integer[] arr) {
      this.arr = arr;
    }
    public methodTest(int[] arr) {
     // ignore the code here 
    }
}

case 2

@RunWith(Parameterized.class)
public class MyTest {
  @Parameterized.Parameters(name = "test with {index}")
  public static Iterable<int[]> data() {
    //here int[][] works 
    return Arrays.asList(new int[][]{ 
            {3, 1, 4, 6, 7, 9},  
            {9, 8, 7, 6, 5, 4},  
  }

  private int[] arr;

  public  MyTest(int[] arr) {
    this.arr = arr;
  }

  public methodTest(int[] arr) {
    // ignore the code here 
  }
}

Upvotes: 0

Views: 2658

Answers (2)

Hank D
Hank D

Reputation: 6471

The reason your Integer version requires more dimensions than the int version is that the first Iterable is Iterable<Integer [][]> which has one more dimension than the second one, Iterable<int[]>.

Upvotes: 0

timbre timbre
timbre timbre

Reputation: 13985

Data itself should always be the same type as data expected by constructor, not by test. Also you've got a bit lost between structure of data() and the data itself. I prefer the following structure, it clearly expresses what we need:

@Parameters
public static Collection<Object[]> data() 
{
    return Arrays.asList(
        new Object[][] 
        { 
            {/* case 1*/},
            {/* case 2*/},
        }
    );
}

Maybe this is not the shortest way, but you will never get lost with it, even with complex data. Every line here, except for /* case 1*/ and /* case 1*/ never changes. On top level we have a collection of arrays (of type object) and we create this collection by providing a 2-dimentional array of objects, with each row expressing test case.

So your Case 1 will become

@Parameterized.Parameters(name = "test with {index}")
public static Collection<Object[]> data() {
    return Arrays.asList(
        new Object[][] 
        { 
            {new Integer[]{3, 1, 4, 6, 7, 9}}, // here
            {new Integer[]{9, 8, 7, 6, 5, 4}}, // here
        }
    );
} 

and Case 2 will become

@Parameterized.Parameters(name = "test with {index}")
public static Collection<Object[]> data() {
    return Arrays.asList(
        new Object[][] 
        { 
            {new int[]{3, 1, 4, 6, 7, 9}}, // here
            {new int[]{9, 8, 7, 6, 5, 4}}, // here
        }
    );
} 

You also need to fix a couple of other problematic lines in your code, e.g. lack of return type on the test. Here's an example of complete runnable and passing test:

package x;

import java.util.Arrays;
import java.util.Collection;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class MyTest 
{
    @Parameterized.Parameters(name = "test with {index}")
    public static Collection<Object[]> data() {
        return Arrays.asList(
                new Object[][] 
                { 
                    {new Integer[]{3, 1, 4, 6, 7, 9}}, // here
                    {new Integer[]{9, 8, 7, 6, 5, 4}}, // here
      });
    }

    private Integer[] arr;

    public MyTest(Integer[] arr) {
      this.arr = arr;
    }

    @Test
    public void methodTest() {
     // test some logic
        System.out.println(arr.length);
    }
}

Upvotes: 1

Related Questions