Search code examples
cucumbercucumber-jvmcucumber-java

Cucumber 6.9 java8, cannot convert from DataTable to custom type


I want to register my custom type in order to automatically get a list from datatable.

Despite there are many sources refering to TypeRegistryConfigurer class, this appears to be deprecated in latest cucumber core version.

I tried to look at this source so I did this:

public class BurpStepDefs implements En {

    private static ObjectMapper objectMapper = new ObjectMapper();

    private static final DataTableType ENTRY =
            new DataTableType(CartInput.Article.class, (java.util.Map<String, String> entry) ->
                    objectMapper.convertValue(entry, CartInput.Article.class));

    private final DataTableTypeRegistry registry = new DataTableTypeRegistry(Locale.ENGLISH);

        public BurpStepDefs() {

        registry.defineDataTableType(ENTRY);

        Given("burped", () -> {

        });

        When("burping", (DataTable o) -> {
            o.asList(CartInput.Article.class); // goes wrong
        });

        Then("burp", (DataTable o) -> {

        });

    }
}

This is the feature file

Feature: operate with customer cart
  Verify all cart operations

  Scenario: scenario burp
    Given burped
    When burping
      | BIRP        | 1 |
      | BYRP        | 1 |
    Then I burp
      | BIRP        | 1 |
      | BYRP        | 1 |

I get the following error:

Can't convert DataTable to List<it.infocert.ecommerce.checkout.model.CartInput$Article>.
Please review these problems:

 - There was no table entry or table row transformer registered for it.infocert.ecommerce.checkout.model.CartInput$Article.
   Please consider registering a table entry or row transformer.

 - There was no default table entry transformer registered to transform it.infocert.ecommerce.checkout.model.CartInput$Article.
   Please consider registering a default table entry transformer.

Note: Usually solving one is enough

Any hint ?

EDIT

After reading @M.P. Korstanje and cucumber specs (At fist I thought docs were deprecated) I solved with this:

DataTableType((java.util.List<String> entry) -> {

    final var output = new CartInput.Article();
    output.setName(entry.get(0));
    output.setQuantity(Integer.parseInt(entry.get(1)));
    output.setOperationId("A");
    return output;
});

Solution

  • You are using bits and bobs from Cucumbers internal API. However the entirety of Cucumbers lambda DSL is contained within the En interface (and it's parent interface LambdaGlue). So to define a single data table entry transformer you would do:

    public class BurpStepDefs implements En {
    
        private static ObjectMapper objectMapper = new ObjectMapper();
    
        public BurpStepDefs()
            DataTableType(
                    (Map<String, String> entry) -> objectMapper.convertValue(entry, CartInput.Article.class));
        }
    }
    

    If you are using a modern IDE you can also type this. inside the constructor and trigger auto-complete (ctrl+space) look the suggestions that are available.