为什么数据提供者在不同的类中,它需要是一个静态方法

时间:2013-10-07 07:02:25

标签: java testng

我有不同类的dataprovider,访问它是不同的testng类。我观察到,如果我不使用“静态”返回它抛出错误。 我想知道这背后的逻辑是什么。 请帮助我。

示例代码:

错误代码:

@DataProvider
public Object[][] testSumInput() {
return new Object[][] { { 5, 5 }, { 10, 10 }, { 20, 20 } };
}

正确代码:

@DataProvider
public static Object[][] testSumInput() {
return new Object[][] { { 5, 5 }, { 10, 10 }, { 20, 20 } };
}

创建数据提供者:

@DataProvider(name="dpProjectDetails")
    public static Object[][] supplyProjectDetails(){
        int noOfRows=CommonMethods.getRowCount(CommonMethods.XLPATH_PROJECT_DETAILS, CommonMethods.SHEET_PROJECT_DETAILS);
        int noOfCell=CommonMethods.getCellCount(CommonMethods.XLPATH_PROJECT_DETAILS, CommonMethods.SHEET_PROJECT_DETAILS);
        Object[][] projectDetails=new Object[noOfRows][noOfCell];


        for(int row=1;row<=noOfRows;row++){
            for(int cell=0;cell<noOfCell;cell++){
                projectDetails[row-1][cell]=CommonMethods.getExcelData(CommonMethods.XLPATH_PROJECT_DETAILS, CommonMethods.SHEET_PROJECT_DETAILS, row, cell);
            }
        }

        return projectDetails;
    }

}

- &gt;访问它:

@Test(dataProvider="DPCustomerData", dataProviderClass=TDCreateCustomer.class)
    public void createNewCustomer(String customerName,String custdescription){
        TDCreateCustomer tdCreateCustomer=new TDCreateCustomer();
        POCreateCustomer poCreateCustomer=new POCreateCustomer();

        tdCreateCustomer.setCustomerName(customerName);
        tdCreateCustomer.setDescription(custdescription);

        poCreateCustomer.createNewCustomer(tdCreateCustomer);
    }

4 个答案:

答案 0 :(得分:1)

这意味着您正在尝试错误地访问它。您永远不应该尝试直接访问它,而应该使变量非静态和私有,并且应该通过非静态公共方法间接访问它们,然后在类的实例上调用方法。

换句话说,你的大多数问题都出现在你没有向我们展示过的代码中 - 你尝试“访问”数据的代码。

答案 1 :(得分:0)

要访问另一个类的方法,要么必须创建类的对象,要么可以通过ClassName.methodName直接访问静态方法,如果它是静态的,则很容易获得另一个类的方法。在这种方法中无需创建整个类的对象,方法可以直接评估只用于相同的目的

答案 2 :(得分:0)

这两个答案对我来说似乎并不完全令人满意。

1)TestNG显然依赖于那里的Reflection。所以我不认为“ClassName.methodName”真的发生在那里。

2)然而,访问类的公共静态方法确实比访问非静态方法简单得多。后者需要首先创建该类的实例。在谈论Reflection时,创建一个任意类的实例可能会非常棘手。

3)毕竟,一般的单元测试概念(如果我说得对)是测试用例应该是可重现的。因此,它们不应该(在大多数情况下)依赖于实例变量,从这个角度来看,静态数据提供者是非常自然的。

4)请注意:当dataProvider驻留在同一个类中时,意味着TestNG已经有了一个实例,所以可以将它设置为非静态。

答案 3 :(得分:0)

应该根据TestNG的当前实现来更新答案。

对于不同类别的数据提供者,静态方法不是强制性的。 TestNG文档提到:

默认情况下,将在当前测试中寻找数据提供者 类或其基类之一。如果您想放数据 提供程序在另一个类中,它必须是静态方法 或 具有非参数构造函数的类 ,然后在该类的位置指定类 可以在dataProviderClass属性中找到。

因此,如果dataprovider方法位于另一个类中,则仅在数据提供者类没有默认构造函数的情况下才需要是静态的。

例如:

以下两项将起作用:

public class MyDataProvider{
   // Java adds a no-arg constructor if there are no other constructors. Hence this works.
   @DataProvider
   public Object[][] dataSet1(){
      return new Object[][]{{1,"a"},{2,"b"}};
   }

public class MyDataProvider{

   public MyDataProvider(int a, String x){
      // do something.
   }

   // static method. Hence this works even though no-args constructor doesn't exist.
   @DataProvider
   public static Object[][] dataSet1(){
      return new Object[][]{{1,"a"},{2,"b"}};
   }

但是下面的代码将不起作用,因为没有no-args构造函数,并且数据提供者方法不是静态的。因此,TestNG无法

  1. 实例化数据提供程序类对象
  2. 或以静态方式调用数据提供者方法。
public class MyDataProvider{

   public MyDataProvider(int a, String x){
      // do something.
   }
   @DataProvider
   public Object[][] dataSet1(){
      return new Object[][]{{1,"a"},{2,"b"}};
   }