Cucumber 没有将特征文件中的数据表中的日期字符串序列化到我的 pojo 中的 LocalDate 字段

我试图弄清楚如何从我的步骤定义中的黄瓜功能文件中解析日期字段.

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) {

}

请注意,我无法访问 Person 类,我确定我必须编写自己的转换器或注册某个库中某人编写的转换器,在搜索完我能看到的唯一选项后,我可以用 pojo 更改它们java.time.LocalDate 字段上的 @Transform.

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.

我目前遇到以下异常

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

我尝试将日期格式更改为 yyyy-MM-dd,这通常有效,但在这种情况下无效.对于如何设置和注册自定义转换器的任何指示,我将不胜感激

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 不支持自动转换新的 java 日期时间类.但它确实支持转换为旧的 util Date 类,因为您没有对数据对象的写访问权限,所以没有用.

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.

为此,您需要在测试运行器上使用 @XStreamConverters 注释.这会将自定义 xstream 转换器添加到 cucumber 中的开箱即用转换器中.

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 {

现在转换器类将字符串解析为 LocalDate 并创建数据对象的集合.这将支持像15-05-2016"这样的日期.只需根据您的日期格式更改 DEFAULT_DATE_PATTERN.

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

}

此外,您将无法干净地使用 @Transform 注释,因为它仅适用于单个值而不是集合.我使用干净,因为需要在混乱的转换器代码中创建对象.

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.

相关文章