使用 DataProvider 将 lambda 作为 testng 参数传递?
Passing lambdas as testng parameters using DataProvider?
我想知道是否有办法从 testng 的数据提供者传递 lambda。所以我想做如下的事情:
@DataProvider(name="checkProvider")
public Object[][] checkProvider() {
return new Object[][]{
"Some string to test", (String string) -> string.length() > 2 //A predicate on how to test response
}
}
然后像这样进行一些测试
@Test(dataProvider="checkProvider")
public void testsomething(String s, Predicate<String> checker) {
//so some operation on s to get a string I want to check
Assert.assertTrue(checker.check(someString));
}
现在我无法执行此操作,因为我得到 lambda 转换的目标类型必须是一个接口。
有没有人知道如何做到这一点,甚至替代方案会很好,这样我就可以实现所需的功能。
编辑:答案在第一条评论中。我试图直接传递一个 lambda,但如果你先声明它然后将它传递给 Object[][] 那么它就可以正常工作。
所以在现实世界的场景中,我通常使用函数式接口的lambda表达式对我们从excel sheet获取的数据执行一些操作。您可能知道,有时为了提供默认值,您的 excelsheet 在列中没有值。有时我们用这个。目前我已经创建了一个简单的示例,其中它正在从列表中检索数据。存储在列表中的数据包含我们不想要的空格。所以为了达到同样的目的,我使用了功能接口。
功能接口:
package testng.package1;
@FunctionalInterface
public interface Trimmer {
String getTrimmedString(String value);
}
测试类:
package testng.package1;
import java.util.ArrayList;
import java.util.List;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class TestClass
{
List<String> dataList = new ArrayList<>();
{
dataList.add("Tomato");
dataList.add(" Cucumber");
dataList.add("Onion ");
dataList.add(" Vegetable that you like ");
}
public String trim(String data)
{
Trimmer trim = (value) -> { return value.trim(); };
return trim.getTrimmedString(data);
}
@DataProvider(name = "data")
public Object[][] getData()
{
Object[][] data = { {"veg1", trim(dataList.get(0))}, {"veg2", trim(dataList.get(1))}, {"veg3", trim(dataList.get(2))}, {"veg4", trim(dataList.get(3))}, };
return data;
}
@Test( dataProvider = "data" )
public void test(String vegId, String vegVal)
{
System.out.println("Vegetable ID: " + vegId + " : " + "Vegetable Name: " + vegVal);
}
}
输出:
[RemoteTestNG] detected TestNG version 7.0.1
Vegetable ID: veg1 : Vegetable Name: Tomato
Vegetable ID: veg2 : Vegetable Name: Cucumber
Vegetable ID: veg3 : Vegetable Name: Onion
Vegetable ID: veg4 : Vegetable Name: Vegetable that you like
PASSED: test("veg1", "Tomato")
PASSED: test("veg2", "Cucumber")
PASSED: test("veg3", "Onion")
PASSED: test("veg4", "Vegetable that you like")
===============================================
Default test
Tests run: 4, Failures: 0, Skips: 0
===============================================
这里的要求是我的评论作为回答:
你可以这样做:
Predicate<String> p = string -> string.length() > 2;
public Object[][] dataProviderMethod() {
return new Object[][] { { "Some string to test" }, { p } };
}
我不知道它对 TestNG 有多大用处。
您只需将数组元素转换为 Function
public Object[][] dataProviderMethod() {
return new Object[][] {{ (Function<String, Boolean>) (string -> string.length() > 2) }};
}
我想知道是否有办法从 testng 的数据提供者传递 lambda。所以我想做如下的事情:
@DataProvider(name="checkProvider")
public Object[][] checkProvider() {
return new Object[][]{
"Some string to test", (String string) -> string.length() > 2 //A predicate on how to test response
}
}
然后像这样进行一些测试
@Test(dataProvider="checkProvider")
public void testsomething(String s, Predicate<String> checker) {
//so some operation on s to get a string I want to check
Assert.assertTrue(checker.check(someString));
}
现在我无法执行此操作,因为我得到 lambda 转换的目标类型必须是一个接口。 有没有人知道如何做到这一点,甚至替代方案会很好,这样我就可以实现所需的功能。
编辑:答案在第一条评论中。我试图直接传递一个 lambda,但如果你先声明它然后将它传递给 Object[][] 那么它就可以正常工作。
所以在现实世界的场景中,我通常使用函数式接口的lambda表达式对我们从excel sheet获取的数据执行一些操作。您可能知道,有时为了提供默认值,您的 excelsheet 在列中没有值。有时我们用这个。目前我已经创建了一个简单的示例,其中它正在从列表中检索数据。存储在列表中的数据包含我们不想要的空格。所以为了达到同样的目的,我使用了功能接口。
功能接口:
package testng.package1;
@FunctionalInterface
public interface Trimmer {
String getTrimmedString(String value);
}
测试类:
package testng.package1;
import java.util.ArrayList;
import java.util.List;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class TestClass
{
List<String> dataList = new ArrayList<>();
{
dataList.add("Tomato");
dataList.add(" Cucumber");
dataList.add("Onion ");
dataList.add(" Vegetable that you like ");
}
public String trim(String data)
{
Trimmer trim = (value) -> { return value.trim(); };
return trim.getTrimmedString(data);
}
@DataProvider(name = "data")
public Object[][] getData()
{
Object[][] data = { {"veg1", trim(dataList.get(0))}, {"veg2", trim(dataList.get(1))}, {"veg3", trim(dataList.get(2))}, {"veg4", trim(dataList.get(3))}, };
return data;
}
@Test( dataProvider = "data" )
public void test(String vegId, String vegVal)
{
System.out.println("Vegetable ID: " + vegId + " : " + "Vegetable Name: " + vegVal);
}
}
输出:
[RemoteTestNG] detected TestNG version 7.0.1
Vegetable ID: veg1 : Vegetable Name: Tomato
Vegetable ID: veg2 : Vegetable Name: Cucumber
Vegetable ID: veg3 : Vegetable Name: Onion
Vegetable ID: veg4 : Vegetable Name: Vegetable that you like
PASSED: test("veg1", "Tomato")
PASSED: test("veg2", "Cucumber")
PASSED: test("veg3", "Onion")
PASSED: test("veg4", "Vegetable that you like")
===============================================
Default test
Tests run: 4, Failures: 0, Skips: 0
===============================================
这里的要求是我的评论作为回答:
你可以这样做:
Predicate<String> p = string -> string.length() > 2;
public Object[][] dataProviderMethod() {
return new Object[][] { { "Some string to test" }, { p } };
}
我不知道它对 TestNG 有多大用处。
您只需将数组元素转换为 Function
public Object[][] dataProviderMethod() {
return new Object[][] {{ (Function<String, Boolean>) (string -> string.length() > 2) }};
}