Метод поставщика нестатических данных TestNG не работает

У меня есть тестовый класс и тестовый метод. Это зависит от метода поставщика данных. Метод поставщика данных находится в другом классе, отличном от тестового класса или одного из его базовых классов. Согласно документации TestNG

Если вы хотите поместить свой поставщик данных в другой класс, это должен быть статический метод или класс с конструктором без аргументов, и вы указываете класс, где его можно найти в атрибуте dataProviderClass.

Тестовый класс:

package test;

import org.testng.Assert;
import org.testng.annotations.Test;

import dataprovider.TestDataProvider;

public class TestClass {
      @Test(dataProvider = "get", dataProviderClass=TestDataProvider.class)
      public void test1(String s1, String s2) {
          Assert.assertEquals(s1.length(), s2.length());
      }
}

Класс поставщика данных:

package dataprovider;

import org.testng.annotations.DataProvider;

public class TestDataProvider {
    @DataProvider(name = "get")
    public Object[][] testData() {
        return new Object[][] {{"a", "b"},{"c", "d"}};
    }
}

Тестовый вывод из Eclipse:

    java.lang.RuntimeException: Can't invoke method public java.lang.Object[][] dataprovider.
TestDataProvider.testData() on this instance of class test.TestClass due to class mismatch
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:75)
    at org.testng.internal.MethodInvocationHelper.invokeDataProvider(MethodInvocationHelper.java:137)
    at org.testng.internal.Parameters.handleParameters(Parameters.java:430)
    at org.testng.internal.Invoker.handleParameters(Invoker.java:1243)
    at org.testng.internal.Invoker.createParameters(Invoker.java:992)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1082)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112)
    at org.testng.TestRunner.privateRun(TestRunner.java:778)
    at org.testng.TestRunner.run(TestRunner.java:632)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:366)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:361)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:319)
    at org.testng.SuiteRunner.run(SuiteRunner.java:268)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1225)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1150)
    at org.testng.TestNG.runSuites(TestNG.java:1075)
    at org.testng.TestNG.run(TestNG.java:1047)
    at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:126)
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:137)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:58)

Кажется, это не работает. Я использую TestNG 6.9.11 и пытался работать как с maven, так и с eclipse. Я использую последний плагин Eclipse-TestNG.


person Sourav Chandra    schedule 12.04.2016    source источник


Ответы (4)


Отказ от ответственности: я тот, кто добавил поддержку нестатических методов из внешнего поставщика данных.

Просто добавьте @Guice в свой класс:

@Guice
public class TestClass {
    @Test(dataProvider = "get", dataProviderClass=TestDataProvider.class)
    public void test1(String s1, String s2) {
        Assert.assertEquals(s1.length(), s2.length());
    }
}

Это еще не упомянутая проблема.

person juherr    schedule 12.04.2016
comment
Спасибо Жюльен. Было бы лучше, если бы документ testNG также имел эту информацию - person Sourav Chandra; 13.04.2016
comment
Вместо этого он должен работать хорошо ;) И я только что создал новую задачу для этого github.com /cbeust/testng/issues/1022 - person juherr; 13.04.2016

Вы уже ответили на свой вопрос, что,

Если вы хотите поместить поставщика данных в другой класс, это должен быть статический метод или класс с конструктором без аргументов.

И в соответствии с дизайном Java это не должно работать, потому что для вызова метода из другого класса либо этот метод должен быть статическим, либо нам нужен объект этого класса.

Метод testData не является статическим, поэтому его нельзя вызывать с помощью класса, и вы не создаете конструктор без аргументов, поэтому не можете создать объект (без объекта нестатический метод не может быть вызван).

Надеюсь, вы поняли мою мысль и получили ответ :)

person Amit Bhoraniya    schedule 12.04.2016
comment
1. Мы можем создать экземпляр, не используя конструктор аргументов, используя отражение и работу. 2. Отсутствие конструктора также означает, что будет конструктор без аргументов, т.е. конструктор по умолчанию будет предоставлен компилятором java. - person Sourav Chandra; 13.04.2016

  1. Сначала TestNG ищет поставщика данных в том же классе. Например:
public class DummyTest {

  @DataProvider(name = "data")
  public Object[][] dummyData() {
      return new Object[][]{
              {"Khan"}, {"Kapoor"}
      };
  }

  @Test(dataProvider = "data")
  public void dataProviderTest(String name){
      System.out.println("My Name is " + name);
  }
  1. Если поставщик данных не найден в том же классе, TestNG ищет его в базовом классе. Например:
public class DummyData {

    @DataProvider(name = "data")
    public Object[][] dummyData() {
        return new Object[][]{
                {"Khan"}, {"Kapoor"}
        };
    }
}
public class DummyTest extends DummyData {
    @Test(dataProvider = "data")
    public void dataProviderTest(String name){
        System.out.println("My Name is " + name);
    }
}
  1. Если у вашего поставщика данных есть конструктор по умолчанию или конструктор без аргументов, вы можете объявить методы поставщика данных как статическими, так и нестатическими. Например
public class DummyData {

    @DataProvider(name = "data")
    public Object[][] dummyData() {
        return new Object[][]{
                {"Khan"}, {"Kapoor"}
        };
    }
}
public class DummyTest {
    @Test(dataProvider = "data", dataProviderClass = DummyData.class)
    public void dataProviderTest(String name){
        System.out.println("My Name is " + name);
    }
}
  1. Если класс DataProvider имеет параметризованные конструкторы, объявите методы поставщика данных как статические, иначе jvm выдаст ошибку. Снимок ошибки от intellij:
objc[48034]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/bin/java (0x1037f04c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x1038b84e0). One of the two will be used. Which one is undefined.
[Utils] [ERROR] [Error] java.lang.InstantiationException: apitestset.users.DummyData
    at java.lang.Class.newInstance(Class.java:427)
    at org.testng.internal.ClassHelper.newInstance(ClassHelper.java:69)
    at org.testng.internal.Parameters.findDataProvider(Parameters.java:582)
    at org.testng.internal.Parameters.findDataProvider(Parameters.java:509)
    at org.testng.internal.Parameters.handleParameters(Parameters.java:691)
    at org.testng.internal.ParameterHandler.handleParameters(ParameterHandler.java:49)
    at org.testng.internal.ParameterHandler.createParameters(ParameterHandler.java:37)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:924)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
    at org.testng.TestRunner.privateRun(TestRunner.java:648)
    at org.testng.TestRunner.run(TestRunner.java:505)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
    at org.testng.SuiteRunner.run(SuiteRunner.java:364)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
    at org.testng.TestNG.runSuites(TestNG.java:1049)
    at org.testng.TestNG.run(TestNG.java:1017)
    at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
    at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:127)
Caused by: java.lang.NoSuchMethodException: apitestset.users.DummyData.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.newInstance(Class.java:412)
    ... 23 more


org.testng.TestNGException: 
Cannot instantiate class apitestset.users.DummyData

    at org.testng.internal.ClassHelper.newInstance(ClassHelper.java:71)
    at org.testng.internal.Parameters.findDataProvider(Parameters.java:582)
    at org.testng.internal.Parameters.findDataProvider(Parameters.java:509)
    at org.testng.internal.Parameters.handleParameters(Parameters.java:691)
    at org.testng.internal.ParameterHandler.handleParameters(ParameterHandler.java:49)
    at org.testng.internal.ParameterHandler.createParameters(ParameterHandler.java:37)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:924)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
    at org.testng.TestRunner.privateRun(TestRunner.java:648)
    at org.testng.TestRunner.run(TestRunner.java:505)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
    at org.testng.SuiteRunner.run(SuiteRunner.java:364)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
    at org.testng.TestNG.runSuites(TestNG.java:1049)
    at org.testng.TestNG.run(TestNG.java:1017)
    at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
    at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:127)
Caused by: java.lang.InstantiationException: apitestset.users.DummyData
    at java.lang.Class.newInstance(Class.java:427)
    at org.testng.internal.ClassHelper.newInstance(ClassHelper.java:69)
    ... 22 more
Caused by: java.lang.NoSuchMethodException: apitestset.users.DummyData.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.newInstance(Class.java:412)
    ... 23 more
person Deepak Attri    schedule 29.01.2019

Для других людей, которые получают ту же ошибку, но не могут ее исправить, следуя другим ответам:

Я заметил, что эта ошибка начала появляться у меня после обновления моего плагина TestNG с 6.X до 7.0 в Eclipse. Я пробовал следовать другим решениям, но единственное, что в итоге сработало для меня, — это полное удаление TestNG (плагин, TestNg Maven и т. д.), а затем настройка сайта обновления для этой конкретной версии TestNG.

person c.bielke    schedule 10.02.2020