0

I am using TestNG to create a test case that uses a DataProvider to feed data to a Factory that is used on a constructor for the test case class to set variables in the class. I have put my DataProvider in a separate class for modularity (as I am expecting my number of test cases to get fairly large and I will need to reuse the DataProviders. A sample is shown below:

Class containing DataProvider:

public class DP {

    @DataProvider(name="testData")
    public Object[][] testData() {
        return new Object[][] {
            { "tc1", "1" },
            { "tc2", "2" },
            { "tc3", "3" }
        };
    }

}

Class containing test cases:

public class SampleTestCase {

    String[] params;

    @Factory(dataProviderClass=DP.class, dataProvider="testData")
    public SampleTestCase(String[] params) {
        System.out.println("Constructor...");
        for(String s : params)
            System.out.println(s);

        this.params = params;
    }

    @Test
    public void tc1() {
        System.out.println("tc1...");
        for(String s : params)
            System.out.println(s);
    }

    @Test(dependsOnMethods="tc1")
    public void tc2() {
        System.out.println("tc2...");
        for(String s : params)
            System.out.println(s);
    }
}

When I try to run this, I get the following errors:

org.testng.TestNGException: The factory method class com.company.automation.regression.SampleTestCase.com.company.automation.regression.SampleTestCase() threw an exception at org.testng.internal.FactoryMethod.invoke(FactoryMethod.java:121) at org.testng.internal.TestNGClassFinder.(TestNGClassFinder.java:153) at org.testng.internal.TestNGClassFinder.(TestNGClassFinder.java:40) at org.testng.TestRunner.initMethods(TestRunner.java:403) at org.testng.TestRunner.init(TestRunner.java:252) at org.testng.TestRunner.init(TestRunner.java:222) at org.testng.TestRunner.(TestRunner.java:171) at org.testng.remote.support.RemoteTestNG6_10$1.newTestRunner(RemoteTestNG6_10.java:28) at org.testng.remote.support.RemoteTestNG6_10$DelegatingTestRunnerFactory.newTestRunner(RemoteTestNG6_10.java:61) at org.testng.SuiteRunner$ProxyTestRunnerFactory.newTestRunner(SuiteRunner.java:623) at org.testng.SuiteRunner.init(SuiteRunner.java:189) at org.testng.SuiteRunner.(SuiteRunner.java:136) at org.testng.TestNG.createSuiteRunner(TestNG.java:1375) at org.testng.TestNG.createSuiteRunners(TestNG.java:1355) at org.testng.TestNG.runSuitesLocally(TestNG.java:1209) at org.testng.TestNG.runSuites(TestNG.java:1133) at org.testng.TestNG.run(TestNG.java:1104) at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114) at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251) at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77) Caused by: org.testng.TestNGException: Cannot instantiate class com.company.automation.regression.SampleTestCase at org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:40) at org.testng.internal.FactoryMethod.invoke(FactoryMethod.java:107) ... 19 more Caused by: java.lang.IllegalArgumentException: wrong number of arguments at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:29) ... 20 more

If I change the parameters of the constructor of SampleTestCase from String[] params to String p1, String p2, then it works correctly. My only problem with that is that I will have large sets of parameters in my DataProvider (i.e. 10+ parameters). I plan on loading those into a hash map once I can get this working...

Thank you in advance!

1 Answers1

0

To avoid the error, create an Object of type String[]:

public class DP {

    @DataProvider(name="testData")
    public static Object[][] testData() {
        return new Object[][] {
            { new String[] {"tc1", "1" }},
            { new String[] {"tc2", "2" }},
            { new String[] {"tc3", "3" }}
        };
    }

}

The two outer dimensions of the Object[][] array are "unwrapped" by TestNG (the first dimension defines separate invocations, the second dimension defines separate arguments to be passed to the test/factory method). To receive an array as an argument, it should be treated as any other Object and get "wrapped" inside this two-dimensional structure.

Edvins
  • 406
  • 5
  • 9