前言

在开发和测试过程中,经常碰见需要构造虚假数据进行测试的情况。这是很常见的场景,很多编程语言都有库提供虚假数据构造:

开源库 datafaker 是 Java 相关虚假数据构造库,它是 java-faker 的替代产品,基于 Java 8 构建,具有最新的库和几个新添加的 Fake Generators。

官方地址: https://www.datafaker.net/

github 地址: https://github.com/datafaker-net/datafaker

pom 依赖:

<dependency>
    <groupId>net.datafaker</groupId>
    <artifactId>datafaker</artifactId>
    <version>1.6.0</version>
</dependency>

一、简单使用

datafaker 支持多种语言,默认英文,中文相关需要设置 Locale, 如下所示。

Faker faker = new Faker(Locale.CHINA);

1.1 姓名

 Name name = faker.name();
 logger.info("{}", name.name()); 

1.2 手机号码

PhoneNumber phoneNumber = faker.phoneNumber();
logger.info("{}", phoneNumber.cellPhone()); 

1.3 地址

Address address = faker.address();
logger.info("{}, {}, {}", address.state(), address.city(), address.streetAddress()); 

1.4 时间

DateAndTime date = faker.date();
logger.info("{}, {}", date.birthday("yyyy年MM月dd日HH时mm分ss秒"), date.between(Timestamp.valueOf("2000-01-01 00:00:00"), Timestamp.valueOf("2099-12-31 23:59:59"))); // 1989年11月02日09时15分42秒, 2048-10-17 21:30:01.383

1.5 大学

University university = faker.university();
logger.info("{}", university.name()); 

1.6 其它

datafaker 提供了非常多的生成器,具体可以见:https://www.datafaker.net/documentation/providers/,但是除了上述部分,都是英文相关的,例如:电影,天气,书籍等等。其实也可以通过配置 yml 文件将电影、天气、书籍等中文数据参与构造假数据,通过看源码发现这些假数据都是通过配置文件配置,然后随机选择的,只不过生成器关于中文的比较少。具体操作可以查看下面 高级用法 自定义

二、高级用法

2.1 集合

// 随机生成3-5个姓名
List<String> names =
        faker.collection(() -> faker.name().name())
             .len(3, 5)
             .generate();
logger.info("{}", names); // [龚思源, 彭弘文, 邱睿渊]

// 随机生成10个身份证号码,其中 30% 为null
List<String> ids = faker.collection(() -> faker.idNumber().validZhCNSsn()).len(10).nullRate(0.3).generate();
logger.info("{}", ids);

2.2 自定义数据

  1. 硬编码数据

    public static class Movie extends AbstractProvider {
        private static final String[] MOVIE_NAMES = new String[]{ "肖申克的救赎", "霸王别姬", "阿甘正传", "泰坦尼克号",
                "这个杀手不太冷", "美丽人生", "千与千寻", "辛德勒的名单", "盗梦空间", "忠犬八公的故事" };
    
        public Movie(Faker faker) {
            super(faker);
        }
    
        public String movie() {
            return MOVIE_NAMES[faker.random().nextInt(MOVIE_NAMES.length)];
        }
    }
    
    public static class MyCustomFaker extends Faker {
        
        public MyCustomFaker(Locale locale) {
                super(locale);
        }
        
        public Movie myMovie() {
            return getProvider(Movie.class, () -> new Movie(this));
        }
    }
    
    @Test
    public void testFaker() {
        MyCustomFaker customFaker = new MyCustomFaker(Locale.CHINA);
        Movie movie = customFaker.myMovie();
        logger.info("{}", movie.movie());
    }
    
  2. 配置文件配置数据

    # coding: utf-8
    zh-CN:
      faker:
        books:
          names: ['代码整洁之道', 'Java 编程思想', 'Java 编程从入门到入土']
          authors: ['马丁(Robert C. Martin)', 'Bruce Eckel', 'aabond']
    
    public static class MyCustomFaker extends Faker {
    
        public MyCustomFaker(Locale locale) {
            super(locale);
        }
        public Movie myMovie() {
            return getProvider(Movie.class, () -> new Movie(this));
        }
    
        public BookFromFile bookFromFile() {
            return getProvider(BookFromFile.class, () -> new BookFromFile(this));
        }
    }
    
    public static class BookFromFile extends AbstractProvider {
        private static final String KEY = "books";
    
        public BookFromFile(Faker faker) {
            super(faker);
            faker.addPath(Locale.CHINA, Paths.get("src/test/java/books.yml"));
        }
    
        public String names() {
            return faker.resolve(KEY + ".names");
        }
        public String authors() {
            return faker.resolve(KEY + ".authors");
        }
    }
    
    @Test
    public void testFaker() {
        MyCustomFaker customFaker = new MyCustomFaker(Locale.CHINA);
       
        BookFromFile bookFromFile = customFaker.bookFromFile();
        logger.info("{}, {}", bookFromFile.names(), bookFromFile.authors());
    }
    

2.3 表达式

String e1 = faker.expression("#{letterify 'test????test'}");        // 将?替换为随机字母
String e2 = faker.expression("#{numerify '#test#'}");               // 将#替换为随机数字
String e3 = faker.expression("#{bothify '?#?#?#?#'}");              // 上述组合
String e4 = faker.expression("#{Name.last_name}#{Name.first_name}");// 能够调用其他Provider类
String e5 = faker.expression("#{templatify 'test','t','q','@'}");   // 能够将字符替换


logger.info("{}, {}, {}, {}, {}", e1, e2, e3, e4, e5);
// testzvkgtest, 6test3, r3t4f3x5, 宋梓晨, qes@

2.4 json 数据

String json = Format.toJson(
                faker.collection(faker::name)
                     .len(2)
                     .build())
        .set("firstName", Name::firstName)
        .set("lastName", Name::lastName)
        .build()
        .generate();

logger.info("{}", json); // [{"firstName": "绍齐", "lastName": "龙"},{"firstName": "聪健", "lastName": "韦"}]

参考

  1. https://www.datafaker.net/documentation/getting-started/
Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐