简体   繁体   中英

Passing lambdas as testng parameters using DataProvider?

I was wondering if there is a way to pass lambdas from testng's data providers. So I want to do something like the following:

    @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
        }
    }

And after that have some test like so

@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));
}

Right now I'm not able to do this as I get Target type of lambda conversion must be an interface . Does anyone have an idea on how to do this or even an alternative would be good so I could achieve the desired functionality.

EDIT: The answer is in the first comment. I was trying to pass a lambda directly but if you first declare it and then pass it in Object[][] then it works fine.

So in real world scenarios, I usually use lambda expression with functional interface to perform some operations on the data we get from excel sheet. You may know that sometimes it may happen that your excelsheet does not have value in a column then in order to provide the default value. sometimes we use this. Currently I have created a simple example in which it is retrieving the data from the list. Data stored in the list contains whitespaces that we do not want. So in order to achieve the same, I have used functional interface.

:

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

As requested here is my comment as an answer:

You can do:

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

I don't know how useful it is with TestNG.

You need just cast array element to Function<String, Boolean>

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM