我有一个代表对象的黄瓜数据表。一些字段需要为Instants,一些字段必须为LocalDates。我环顾四周,有关解析Java 8时间对象的所有文章似乎都是几年前的,我想知道是否有一个库可以为我处理这个问题。

最佳答案

您可能首先要考虑是否需要在方案中表达确切的日期。 If the dates are merely incidental to the scenario you should strongly consider removing them from the feature file.

但是,如果您必须:jackson-databind是可行的方法。它主要用于将POJO与JSON(反序列化)。由于Cucumbers数据表可以表示为json映射列表,因此我们可以利用它。

对于这个解释,我假设您使用的是Cucumber-JVM 4和ISO8601日期格式。如果您使用其他日期格式,则还有其他资源可以帮助您。

因此,假设您执行了以下步骤:

    Given an object with dates
      | localDate  | instant                  |
      | 2019-09-05 | 2015-06-02T21:34:33.616Z |


首先定义一个接受对象的步骤。您的对象必须是POJO。

import io.cucumber.java.en.Given;

import java.time.Instant;
import java.time.LocalDate;

public class DateSteps {

    @Given("an object with dates")
    public void and_object_with_dates(Dates dates) {

    }

    public static class Dates {
        public LocalDate localDate;
        public Instant instant;

    }
}


添加对Jackson和JSR310模块的依赖关系,以添加对JSR310添加的日期时间对象的支持。

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.8</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>2.9.8</version>
        </dependency>


将黄瓜类型注册表配置为使用启用了JSR310模块的对象映射器来转换数据表单元格,条目和参数类型。

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JSR310Module;
import io.cucumber.core.api.TypeRegistry;
import io.cucumber.core.api.TypeRegistryConfigurer;
import io.cucumber.cucumberexpressions.ParameterByTypeTransformer;
import io.cucumber.datatable.TableCellByTypeTransformer;
import io.cucumber.datatable.TableEntryByTypeTransformer;

import java.lang.reflect.Type;
import java.util.Locale;
import java.util.Map;

import static java.util.Locale.ENGLISH;

public class ParameterTypes implements TypeRegistryConfigurer {

    @Override
    public Locale locale() {
        return ENGLISH;
    }

    @Override
    public void configureTypeRegistry(TypeRegistry typeRegistry) {
        Transformer transformer = new Transformer();
        typeRegistry.setDefaultDataTableCellTransformer(transformer);
        typeRegistry.setDefaultDataTableEntryTransformer(transformer);
        typeRegistry.setDefaultParameterTransformer(transformer);
    }

    private static class Transformer implements ParameterByTypeTransformer, TableEntryByTypeTransformer, TableCellByTypeTransformer {
        ObjectMapper objectMapper = new ObjectMapper().registerModule(new JSR310Module());

        @Override
        public Object transform(String s, Type type) {
            return objectMapper.convertValue(s, objectMapper.constructType(type));
        }

        @Override
        public <T> T transform(Map<String, String> map, Class<T> aClass, TableCellByTypeTransformer tableCellByTypeTransformer) {
            return objectMapper.convertValue(map, aClass);
        }

        @Override
        public <T> T transform(String s, Class<T> aClass) {
            return objectMapper.convertValue(s, aClass);
        }
    }
}


现在,您可以在任何地方使用JSR310日期。

10-05 18:33