Im trying to figure out how to parse date fields from my cucumber feature files in my step definitions.
class Person{
String name
LocalDate dob
}
scenario: do something with people
Given list of people:
|name|dob|
| john| 20-09-2001|
@Given("^list of people:")
public void doSomething(List<Person> people) {
}
Please note i have no access to the Person class, Im sure i have to either write my own converter or register a converter written by someone from some library, after searching around the only options i can see are to change them pojo with a @Transform on the java.time.LocalDate field.
I'm currently getting the following exception
cucumber.runtime.CucumberException: cucumber.deps.com.thoughtworks.xstream.converters.ConversionException: Cannot deserialize object with new readObject()/writeObject() methods
---- Debugging information ----
class : java.time.LocalDate
required-type : java.time.LocalDate
converter-type : cucumber.deps.com.thoughtworks.xstream.converters.reflection.SerializableConverter
path : /list/com.pkg.Person/dob
I have tried changing the dateformat to yyyy-MM-dd, that usually works but not on this occasion. I would be gratefull for any pointers on how to setup and register a custom converter
my cucumber dependencies are as follows, i can chane these if required to newer versions if it makes any difference.
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>2.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-spring</artifactId>
<version>2.4.0</version>
</dependency>
Cucumber does not support automatic conversion of the new java date time classes. But it does support conversion to the old util Date class which is of no use as you do not have write access to the dataobject.
For this to work you will need to use the @XStreamConverters
annotation on the test runner. This will add the custom xstream converter to the out of the box converters in cucumber.
@RunWith(Cucumber.class)
@CucumberOptions(plugin = { ""}, tags = { "" }, glue = "stepdefs",
features = "" ) --> use your own values
@XStreamConverters(@XStreamConverter(LocalDateCon.class))
public class RunSampleTest {
Now the converter class to parse the string into LocalDate
and create the collection of dataobjects. This will support dates like "15-05-2016
". Just change the DEFAULT_DATE_PATTERN
according to your date format.
public class LocalDateCon implements Converter{
public boolean canConvert(Class type) {
//return type.equals(LocalDate.class);
return LocalDate.class.isAssignableFrom(type);
}
private static final String DEFAULT_DATE_PATTERN = "dd-MM-yyyy";
private static final DateTimeFormatter DEFAULT_DATE_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_DATE_PATTERN);
public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
LocalDate date = (LocalDate) value;
String result = date.format(DEFAULT_DATE_FORMATTER);
writer.setValue(result);
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
LocalDate result = LocalDate.parse(reader.getValue(), DEFAULT_DATE_FORMATTER);
return result;
}
}
Also you will not be able to use @Transform
annotation cleanly as it works only for a single value and not a collection. I used cleanly as one will need to do the object creation in the converter code which is messy.