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

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

Если вы хотите поместить свой поставщик данных в другой класс, это должен быть статический метод или класс с конструктором, не являющимся аргументом arg, и вы указываете класс, где его можно найти в атрибуте 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.

5 ответов

Решение

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

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

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

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

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

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

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

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

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

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

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

  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. Если ваш DataProvider имеет конструктор по умолчанию или конструктор без аргументов, вы можете объявить методы поставщика данных как статические, так и нестатические. Например
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 имеет параметризованные конструкторы, объявите методы 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

Он был сломан между 6.8.x и 6.10.x. Использование любой версии, отличной от этого диапазона, должно решить вашу проблему.

Другие вопросы по тегам