Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create multiple parameter sets in one parameterized class (junit)

Currently I have to create a parameterized test class for every method that I want to test with several different inputs. Is there a way to add this together in one file?

Right now there's CalculatorTestAdd.java which has a set of parameters that are used to check if the Add() function works properly. Is there a possbility for me to 'connect' this set to the Add() function and create an additional set meant for the Subtract() method and add this method in the same test class, resulting in one file called CalculatorTest.java?

like image 695
Jeroen Vannevel Avatar asked Dec 29 '12 13:12

Jeroen Vannevel


2 Answers

This answer is similar to Tarek's one (the parametrized part), although I think it is a bit more extensible. Also solves your problem and you won't have failed tests if everything is correct:

@RunWith(Parameterized.class) public class CalculatorTest {     enum Type {SUBSTRACT, ADD};     @Parameters     public static Collection<Object[]> data(){         return Arrays.asList(new Object[][] {           {Type.SUBSTRACT, 3.0, 2.0, 1.0},           {Type.ADD, 23.0, 5.0, 28.0}         });     }      private Type type;     private Double a, b, expected;      public CalculatorTest(Type type, Double a, Double b, Double expected){         this.type = type;         this.a=a; this.b=b; this.expected=expected;     }      @Test     public void testAdd(){         Assume.assumeTrue(type == Type.ADD);         assertEquals(expected, Calculator.add(a, b));     }      @Test     public void testSubstract(){         Assume.assumeTrue(type == Type.SUBSTRACT);         assertEquals(expected, Calculator.substract(a, b));     } } 
like image 176
nessa.gp Avatar answered Sep 21 '22 14:09

nessa.gp


Another pure JUnit but yet elegant solution in my view is to encapsulate each parameterized test(s) in their own inner static class and use the Enclosed test runner on the top level test class. This allows you not only to use different parameter values for each test independently of each other but also to test methods with completely different parameters.

This is how it would look like:

@RunWith(Enclosed.class) public class CalculatorTest {    @RunWith(Parameterized.class)   public static class AddTest {      @Parameters     public static Collection<Object[]> data() {       return Arrays.asList(new Object[][] {           { 23.0, 5.0, 28.0 }       });     }      private Double a, b, expected;      public AddTest(Double a, Double b, Double expected) {       this.a = a;       this.b = b;       this.expected = expected;     }      @Test     public void testAdd() {       assertEquals(expected, Calculator.add(a, b));     }   }    @RunWith(Parameterized.class)   public static class SubstractTest {      @Parameters     public static Collection<Object[]> data() {       return Arrays.asList(new Object[][] {           { 3.0, 2.0, 1.0 }       });     }      @Parameter(0)     private Double a;     @Parameter(1)     private Double b;     @Parameter(2)     private Double expected;      @Test     public void testSubstract() {       assertEquals(expected, Calculator.substract(a, b));     }   }    @RunWith(Parameterized.class)   public static class MethodWithOtherParametersTest {      @Parameters     public static Collection<Object[]> data() {       return Arrays.asList(new Object[][] {           { 3.0, 2.0, "OTHER", 1.0 }       });     }      private Double a;     private BigDecimal b;     private String other;     private Double expected;      public MethodWithOtherParametersTest(Double a, BigDecimal b, String other, Double expected) {       this.a = a;       this.b = b;       this.other = other;       this.expected = expected;     }      @Test     public void testMethodWithOtherParametersTest() {       assertEquals(expected, Calculator.methodWithOtherParametersTest(a, b, other));     }   }    public static class OtherNonParameterizedTests {      // here you can add any other test which is not parameterized      @Test     public void otherTest() {       // test something else     }   } } 

Note the usage of the @Parameter annotation in the SubstractTest, which I consider more readable. But this is more a matter of taste.

like image 35
Alex Avatar answered Sep 21 '22 14:09

Alex