0

I would like to perform a JUnit Parametrized test with data being external. I have a list of objects and just need to know how I can convert that to a collection of object arrays. I see the below stack overflow question, but I want to add data from a file which is read from my method.

Parameterized JUnit tests with non-primitive parameters?

Working code: something like this:

@RunWith(Parameterized.class)
public class sampletest {

  private BranchMailChildSample branch;

  public sampletest(BranchMailChildSample branch)
  {
    this.branch = branch;
  }

  @Parameters
  public static Collection<Object[]> data()
  {
    String excel = "C:\\Resources\\TestData\\ExcelSheets\\BranchMail\\branchmail_TestData.xlsx";
    ExcelMarshallerTool tool = new ExcelMarshallerTool(excel);
    List<BranchMailChildSample> items = tool.unmarshallExcel(BranchMailChildSample.class);

   //RIGHT HERE I NEED HELP: Convert list to Collection<Object[]>

    //return items as Collection of object arrays 
  }

  @Test
  public void test()
  {
    System.out.println(branch.toString());
  }
}
Community
  • 1
  • 1
CodyK
  • 3,426
  • 4
  • 36
  • 52
  • It will be better to create the expected `List` and test the relevant code.. – Luiggi Mendoza Apr 14 '15 at 16:09
  • I can do that, but I would like the nicety of having it show as multiple tests in the junit plugin. If one object in that list fails, then the entire test will fail. It will take more time to debug, rather than if I can have a snapshot of each piece of data failing. – CodyK Apr 14 '15 at 16:14
  • You can declare the list as a field of the class, initialize it and fill it in a `@Before` method, then use it as desired. It's not the same as when using other frameworks, but it's an option. – Luiggi Mendoza Apr 14 '15 at 16:16
  • I can do that but that is not ideal. I want it to show in the runner how a parametrized test looks and I need to be able to see at a birds eye view, which sets of data are failing. I originally was using this library called Feed4Junit but then found out, it doesn't work well with JUnit 4.12 databene.org/feed4junit – CodyK Apr 14 '15 at 16:49

4 Answers4

2

You don't have to convert the list.

@RunWith(Parameterized.class)
public class SampleTest {

  @Parameters(name = "{0}")
  public static List<BranchMailChildSample> data() {
    String excel = "C:\\Resources\\TestData\\ExcelSheets\\BranchMail\\branchmail_TestData.xlsx";
    ExcelMarshallerTool tool = new ExcelMarshallerTool(excel);
    return tool.unmarshallExcel(BranchMailChildSample.class);
  }

  @Parameter(0)
  public BranchMailChildSample branch;

  @Test
  public void test() {
    System.out.println(branch.toString());
  }
}

I used field injection, because it needs less code than constructor injection. Setting the name to the object under test prints more helpful output. Please have a look at the documentation of the Parameterized runner.

You can use constructor injection if you don't like the public field.

@RunWith(Parameterized.class)
public class SampleTest {

  @Parameters(name = "{0}")
  public static List<BranchMailChildSample> data() {
    String excel = "C:\\Resources\\TestData\\ExcelSheets\\BranchMail\\branchmail_TestData.xlsx";
    ExcelMarshallerTool tool = new ExcelMarshallerTool(excel);
    return tool.unmarshallExcel(BranchMailChildSample.class);
  }

  private final BranchMailChildSample branch;

  public SampleTest(BranchMailChildSample branch) {
    this.branch = branch;
  }

  @Test
  public void test() {
    System.out.println(branch.toString());
  }
}
Stefan Birkner
  • 24,059
  • 12
  • 57
  • 72
0

That's why I would suggest you to use TestNG instead if possible. It's work the same as JUnit but you can use a internal or external DataProvider, execute methods at a given order... It is much more convenient to use

//This method will provide data to any test method that declares that its Data Provider
//is named "test1"
@DataProvider(name = "test1")
public Object[][] createData1() {
 return new Object[][] {
   { "Cedric", new Integer(36) },
   { "Anne", new Integer(37)},
 };
}

//This test method declares that its data should be supplied by the Data Provider
//named "test1"
@Test(dataProvider = "test1")
public void verifyData1(String n1, Integer n2) {
 System.out.println(n1 + " " + n2);
}
  • Please, at least provide how can this be achieved using TestNG, otherwise it should be a comment. – Luiggi Mendoza Apr 14 '15 at 16:12
  • I have provide a link of how to use it in my anserw: http://testng.org/doc/documentation-main.html#parameters-dataproviders –  Apr 14 '15 at 16:12
  • It is not possible. I would like to use TestNG but we got stuck with JUnit, since that is what is already being leveraged. – CodyK Apr 14 '15 at 16:12
  • Ok that's a problem but for information TestNG can run JUnit test also. –  Apr 14 '15 at 16:14
0

Actually, if you use JUnit 4.12 and the theories runner, something like this should just work:

@RunWith(Theories.class)
public class MyTest 
{
   @DataPoints public static List<MyClass> myFunctionThatReturnsTestData() 
   {
        // TODO
   }

   @Theory
   public void canDoTheThing(MyClass m) throws Exception {
Stefan Birkner
  • 24,059
  • 12
  • 57
  • 72
soru
  • 5,464
  • 26
  • 30
  • While, this will work, I will still run into issues. The first problem, is the junit plugin runner will report it as a single test. I want each piece of data to show up as a different test so I can get a birds eye view of what passed and what failed. Secondly, when using Therories, if I use an assert it will hault the test and not run the others. Using Assums will mark the test as a pass in the runner if it fails, so I don't want to use that either. – CodyK Apr 14 '15 at 16:43
  • I originally was using this library called Feed4Junit but then found out, it doesn't work well with JUnit 4.12 http://databene.org/feed4junit – CodyK Apr 14 '15 at 16:47
0

I got it to work doing this:

    List<BranchMailChildSample> items = tool.unmarshallExcel(BranchMailChildSample.class);

    Collection<Object[]> data = new ArrayList<Object[]>();

    for(BranchMailChildSample item : items)
    {
        Object[] objItem = new Object[] { item };
        data.add(objItem);
    }

    return data;
CodyK
  • 3,426
  • 4
  • 36
  • 52