使用TestNG @DataProvider,它在调用返回Object [] []的method()时返回“[Utils] [ERROR] [Error] java.lang.NullPointerException”

时间:2017-07-15 14:04:48

标签: testng

我有一个类,其中包含连接到数据库的方法并获取所有用户的用户名和密码。我将该方法传递给TestNG @DataProvider,因此@Test可以使用它。

摘要如下所示

public class testing2 {

  @Test(dataProvider = "dp")
  public void f(String userName, String password) {
    System.out.println(userName);
    System.out.println(password);
  }

  //Option 1 : Won't work
  //Will return [Utils] [ERROR] [Error] java.lang.NullPointerException
  @DataProvider
  public Object[][] dp() throws ClassNotFoundException, SQLException {
      //Creating an instance from the class where the method is located and then calling that method credentials
      Object[][] data = instance_of_the_class.method_to_fetch_datas_from_DB();
      return data;



      //Option 2 : works fine
      @DataProvider
      public Object[][] dp() throws ClassNotFoundException, SQLException {
          //Put the logic directly here without calling any method
          //Logic ...
          //Logic ...
          //Logic ...
          //End result is Object[][] data  
          return data;

详细方法如下所示

public Object[][] credentials(String driverClass,
  String DBuserName, String DBpassword, String jdbcAddress,
  String company1, String company2)
throws ClassNotFoundException, SQLException {

  Class.forName(driverClass);
  Connection con = DriverManager.getConnection(jdbcAddress, DBuserName, DBpassword);
  Statement s = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);


  ResultSet rs = s
    .executeQuery("select * from users where COMPANYID = " + company1 + "or COMPANYID = " + company2);

  int total = 0;
  while (rs.next() == true) {
    total++;
  }


  Object[][] data = new Object[total][2];

  rs.beforeFirst();
  int a = 0;

  while (rs.next()) {
    data[a][0] = rs.getString("USERNAME");
    data[a][1] = rs.getString("PASSWD");
    a++;
    System.out.println(rs.getString("USERNAME"));
  }


  return data;
}

我单独测试了这个方法,它运行正常。

现在在我的主要测试类中,我开始使用此方法。看起来像这样

public class testing2 {
	
  @Test(dataProvider = "dp")
  public void f(String userName, String password) {
	System.out.println(userName);
	System.out.println(password);
  }
  
  
  @DataProvider
  public Object[][] dp() throws ClassNotFoundException, SQLException {
      //Creating an instance from the class where method credentials() is located and then calling that method credentials
	  Object[][] data =searching.credentials("interbase.interclient.Driver", "DBuserName", "DBpassword", "jdbc:interbase://10.110.10.10:3050/e:/Databases/DATABASE.IB", "5204", "5201");
	  return data;

当我跑它时,它会抛出我

[Utils] [ERROR] [Error] java.lang.NullPointerException
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at ssdPage.SSDSearchPage.credentials(SSDSearchPage.java:52)
    at ssdTest.SSDtest.getData(SSDtest.java:106)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:108)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:55)
    at org.testng.internal.MethodInvocationHelper.invokeMethodNoCheckedException(MethodInvocationHelper.java:45)
    at org.testng.internal.MethodInvocationHelper.invokeDataProvider(MethodInvocationHelper.java:115)
    at org.testng.internal.Parameters.handleParameters(Parameters.java:509)
    at org.testng.internal.Invoker.handleParameters(Invoker.java:1308)
    at org.testng.internal.Invoker.createParameters(Invoker.java:1036)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1126)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:126)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
    at org.testng.TestRunner.privateRun(TestRunner.java:744)
    at org.testng.TestRunner.run(TestRunner.java:602)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:380)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:375)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340)
    at org.testng.SuiteRunner.run(SuiteRunner.java:289)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1301)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1226)
    at org.testng.TestNG.runSuites(TestNG.java:1144)
    at org.testng.TestNG.run(TestNG.java:1115)
    at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:132)
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:230)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:76)

但是如果我不调用方法凭证()但我只是将逻辑直接放在@DataProvider中,它就可以正常工作。代码示例如下所示

public class testing2 {

  @Test(dataProvider = "dp")
  public void f(String userName, String password) {
    System.out.println(userName);
    System.out.println(password);
  }

  @DataProvider
  public Object[][] dp() throws ClassNotFoundException, SQLException {

    Class.forName("interbase.interclient.Driver");
    Connection con = DriverManager.getConnection("jdbc:interbase://10.110.10.10:3050/e:/Databases/DATABASE.IB", "DBuserName", "DBpassword");
    Statement s = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);


    ResultSet rs = s
      .executeQuery("select * from users where COMPANYID = " + "5204" + "or COMPANYID = " + "5201");

    int total = 0;
    while (rs.next() == true) {
      total++;
    }


    Object[][] data = new Object[total][2];

    rs.beforeFirst();
    int a = 0;

    while (rs.next()) {
      data[a][0] = rs.getString("USERNAME");
      data[a][1] = rs.getString("PASSWD");
      a++;
      System.out.println(rs.getString("USERNAME"));
    }


    return data;
  }
}

为什么我无法在TestNG @DataProvider中调用返回Object [][]的方法? 为什么逻辑必须直接写在@DataProvider中?

谢谢。

3 个答案:

答案 0 :(得分:1)

您似乎从此行触发了数据提供商的NullPointerException

Object[][] data =searching.credentials("interbase.interclient.Driver", "DBuserName", "DBpassword", "jdbc:interbase://10.110.10.10:3050/e:/Databases/DATABASE.IB", "5204", "5201");

我没看到,你在哪里实例化对象searching。我猜这就是造成NullPointerException的原因。您可以尝试将方法credentials()设为静态,方法是在其定义中添加static关键字吗?希望这应该为你解决问题。

答案 1 :(得分:1)

<a data-toggle="collapse" data-parent="#accordion" th:href="'#collapse' + ${iterStat.index}" th:text="${p.key}">

出于任何原因,您认为<div th:id="'collapse' + ${iterStat.index}" class="panel-collapse collapse in"> java.lang.NullPointerException at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at ssdPage.SSDSearchPage.credentials(SSDSearchPage.java:52) null driverClass。 但是,您没有提供足够的细节来帮助您。

答案 2 :(得分:-1)

您需要在功能中添加静态。 来自文档:

  

查找数据提供者的类。如果没有指定,   数据提供程序将查看当前测试方法的类   或其中一个基类。如果指定了此属性,则为数据   provider方法需要在指定的类上是静态的。

http://testng.org/doc/documentation-main.html