使用DataProvider传递lambda表达式作为TestNG参数?

3
我想知道是否有一种方法可以从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转换必须是一个接口

有没有人有想法如何做到这一点,或者甚至提供一个替代方案,以便我可以实现所需的功能。

编辑:答案在第一个评论中。如果您先声明它,然后将其传递给Object [][],则可以正常工作。


你可以这样做:Predicate<String> p = string -> string.length() > 2; public Object[][] dataProviderMethod() { return new Object[][] { { "用于测试的一些字符串" }, { p } }; } 我不知道在TestNG中它有多有用。 - undefined
请将以下与编程相关的内容从英文翻译成中文。只返回翻译后的文本:请将此作为答案。非常感谢。 - undefined
3个回答

3

你只需要将数组元素转换为Function<String, Boolean>

public Object[][] dataProviderMethod() { 
    return new Object[][] {{ (Function<String, Boolean>) (string -> string.length() > 2) }}; 
} 

这导致了错误:org.testng.TestNGException: 无法使用[interface java.util.function.Function]注入@Test注释的方法[testMethod]。 有关本地依赖注入的更多信息,请参阅https://testng.org/doc/documentation-main.html#native-dependency-injection。 - undefined

2

根据您的要求,这是我的评论:

您可以执行以下操作:

Predicate<String> p = string -> string.length() > 2; 
public Object[][] dataProviderMethod() { 
    return new Object[][] { { "Some string to test" }, { p } }; 
} 

我不知道TestNG有多有用。


1
在实际场景中,我通常使用带有函数接口的lambda表达式来对从Excel表格中获取的数据执行一些操作。您可能知道,有时候会出现在某列中没有值的情况,为了提供默认值,我们有时会使用这种方式。目前,我已经创建了一个简单的示例,它正在从列表中检索数据。存储在列表中的数据包含我们不想要的空格。因此,为了实现相同的功能,我使用了函数接口。 函数接口:
package testng.package1;


@FunctionalInterface
public interface Trimmer {

    String getTrimmedString(String value);

}

TestClass:

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
===============================================

感谢提供的链接,但我已经了解了lambda表达式,我想知道是否有一种方法可以参数化testng测试以使用lambda表达式。 - undefined
非常抱歉。我会为您创建一个带有一些实时场景的项目,感谢冠状病毒封锁期间,我有空闲时间来完成这个任务 :) - undefined
感谢您的努力,但我事先不知道将应用谓词的值。在我编写的测试中,我将从 REST 调用中获取值,然后才能应用谓词。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接