views:

1284

answers:

4

Can I have more than one method with @Parameters in junit test class which is running with Parameterized class ?

@RunWith(value = Parameterized.class)
public class JunitTest6 {

 private String str;

 public JunitTest6(String region, String coverageKind,
     String majorClass, Integer vehicleAge, BigDecimal factor) {
    this.str = region;
 }

  @Parameters
 public static Collection<Object[]> data1() {
   Object[][] data = {{some data}}

   return Arrays.asList(data);
 }

 @Test
 public void pushTest() {
   System.out.println("Parameterized str is : " + str);
   str = null;
 }

 @Parameters
 public static Collection<Object[]> data() {
   Object[][] data = {{some other data}}
   return Arrays.asList(data);
 }

 @Test
 public void pullTest() {
   System.out.println("Parameterized new str is  : " + str);
   str = null;
 }
}
+2  A: 

Probably the data1 method, but no guarantee of that, it'll use whichever one the JVM gives junit4 first.

Here's the relevant code from junit:

private FrameworkMethod getParametersMethod(TestClass testClass) throws Exception {
    List<FrameworkMethod> methods= testClass.getAnnotatedMethods(Parameters.class);
    for (FrameworkMethod each : methods) {
        int modifiers= each.getMethod().getModifiers();
            if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))
                return each;
    }

    throw new Exception("No public static parameters method on class " + testClass.getName());
}

So the first public, static annotated method that it finds will be used, but it may find them in any order.

Why do you have uour test written that way? You should only have one @Parameters-annotated method.

skaffman
Thank you skaffman. Actually I wanted test two different behavior valid one and invalid one in same test class with different methods.
RN
Ah OK. If you're keen, then you could write your own Test runner implementation (copy the source for the Parameterized and modify it to make your own) to do that, but the built-in Parameterized runner is quite crude.
skaffman
hmm, thanks anyways.
RN
+1  A: 

You can use the Theories runner (search for the word theories at that link) to pass different parameters to different methods.

Yishai
yes this could be the solution, Thank you Yishai.
RN
+1  A: 

It's not designated to have more than one data method. You can see it in skaffman's answer.

Why it's not provided to implement two data methods?
The answer could be: Coupling.

Is it too complex to split this test up into two testcases? You would be able to introduce a small inheritance and share common methods. With two testcases you could provide two separated data methods and test your stuff very well.

I hope it helps.

furtelwart
that's right it can easily achieved using to separate test cases. Thank you guerda, for your response. Actually I was looking for the same way which TestNG uses, providing data providers for each method.
RN
An upvote would comfort me ;)
furtelwart
A: 

You can create inner classes for each set of methods that operate on the same parameters. For example:

public class JunitTest6 {

 @RunWith(value = Parameterized.class)
 public static class PushTest{
  private String str;
  public PushTest(String region) {
   this.str = region;
  }

  @Parameters
  public static Collection<Object[]> data() {
   Object[][] data = {{some data}}

   return Arrays.asList(data);
  }

  @Test
  public void pushTest() {
   System.out.println("Parameterized str is : " + str);
   str = null;
  }
 }

 @RunWith(value = Parameterized.class)
 public static class PullTest{
  private String str;
  public PullTest(String region) {
   this.str = region;
  }

  @Parameters
  public static Collection<Object[]> data() {
   Object[][] data = {{some other data}}
   return Arrays.asList(data);
  }

  @Test
  public void pullTest() {
   System.out.println("Parameterized new str is  : " + str);
   str = null;
  }
 }
}
aeriform