Search code examples
javacucumber

Java Cucumber with optional Datatable parameter


I am trying to write a component test were it would be ideal where I can either pass in the values if needed to configure or else use a default values.

Employee.class

public class Employee {
public static final Employee DEFAULT_EMPLOYEE = Employee.builder()
.employeName("Jack")
.employeNumber(01)
.build();


  String employeeName;
  Integer employeeNumber;
....
}

employee.feature

Given a employee is created
or
Given a employee is created
| employeeName | employeeNumber | 
| John         | 123.           | 

employeeStep.java

@When("a/the employee is created")
  public void createEmployee(Employee employee){
  service.createEmpoyee(employee);
}

EmployeeTransformer.java

public class EmployeeTransformer {

@DataTableType
public Employee transform(Map<String, String> data) {
  EmployeeBuilder eb = DEFAULT_EMPLOYEE.toBuilder();

  Optional.ofNullable(data.get(EMPLOYEEE_NAME))
  .map(String::valueOf)
  .ifPresent(eb::employeeName);

  ....

  return eb.build();
 }
}

Above transformer handles the step when dataTable parameters is passed in the step. The problem is that when a step with no data table is added to a scenario, it throws the following exception:

io.cucumber.core.exception.CucumberException: Step [Given a employee is created] is defined with 1 parameters at 'com. createEmployee.steps. employeeStep. createEmployee(io.cucumber.datatable.DataTable)'. However, the gherkin step has 0 arguments.

Solution

  • You defined a step definition that takes a DataTable argument but your example to use a default employee uses a step with zero arguments. That is not valid in Gherkins. In fact, this is not valid in Java!

    When you create a function in Java

    public void myMethod(String arg) {
    ...
    }
    

    Even if the method accept a null value, I must pass a reference to something when I call that method, even if the value is null. This

    myObj.myMethod();
    

    is not the same as

    myObj.myMethod(null);
    

    Those are two different methods. Don't you agree? Passing no arguments to a function is not the same as passing null arguments. To make it more relevant to your specific issue, passing no DataTable is not the same as passing a null DataTable, or passing no DataTable rows is not the same as passing empty or null rows. This is what the exception is telling you. You are passing nothing to a function that expects something to be passed to it.

    Although I have never taken this approach, I believe you MUST add an empty row to your DataTable for your default case to work and I am not even sure if that would work either. Try something like this

    Given a employee is created
    | employeeName | employeeNumber |
    |              |                |
    | John         | 123.           | 
    

    Now it is up to Gherkin to see if the above case is supported. But the above is the equivalent (in Java) of passing null or empty arguments rather than no arguments. That said, the above, if it works, I am not sure if it will create a null map. For starters, I don't know what version of Cucumber you are using. I think newer versions replace empty cells with null but I am not certain how this will work, even if you use a newer version, since the key value is null in the above example. This solution may not fully work, but it should get you close.