preface

In daily testing, we often need to prepare a lot of test data in advance to verify the business logic. Of course, simple data types can be implemented through the Random class of the JDK. However, Random is not suitable for a complex class or when there are special requirements on the format of parameters. In this case, some framework that can generate test data is needed.

The relevant framework

In the actual research, I found two generation frameworks that are good in my opinion. They are:

  1. jmockdata
  2. java-faker

Below, I’ll go through the pros and cons of each of these frameworks, as well as their application scenarios. Without saying a word, just start coding.

JmockData

First up is the JmockData framework, which is officially defined as follows:

A tool framework that implements data that simulates the instantiation and random initialization of JAVA types or objects.

Rely on

  <dependency>
     <groupId>com.github.jsonzou</groupId>
     <artifactId>jmockdata</artifactId>
     <version>4.2.0</version>
   </dependency>
Copy the code

Base type data generation

    @Test
    public void testBaseType(a){
        // Base data type
        System.out.println(JMockData.mock(byte.class));
        System.out.println(JMockData.mock(int.class));
        System.out.println(JMockData.mock(long.class));
        System.out.println(JMockData.mock(double.class));
        System.out.println(JMockData.mock(float.class));
        System.out.println(JMockData.mock(String.class));
        System.out.println(JMockData.mock(BigDecimal.class));

        // An array of underlying data types
        System.out.println(JMockData.mock(byte[].class));
        System.out.println(JMockData.mock(int[].class));
        System.out.println(JMockData.mock(long[].class));
        System.out.println(JMockData.mock(double[].class));
        System.out.println(JMockData.mock(float[].class));
        System.out.println(JMockData.mock(String[].class));
        System.out.println(JMockData.mock(BigDecimal[].class));
    }
Copy the code

The results
0
2610
3401
8582.18
7194.44
5Xu7
9051.92
[B@7fbe847c
[I@41975e01
[J@c2e1f26
[D@dcf3e99
[F@6d9c638
[Ljava.lang.String;@7dc5e7b4
[Ljava.math.BigDecimal;@1ee0005
Copy the code

JavaBean type data generation

    /** * Java bean test */
    @Test
    public void testJavaBean(a){
        Person mock = JMockData.mock(Person.class);
        System.out.println(mock);
    }
Copy the code

The results
Person[address=RrayfQIK,age=5863,idCard=SDn,name=j]
Copy the code

As you can see here, use jmockData.mock (xx.class); You can easily generate a JavaBean. The framework iterates through reflection to get the attributes and types of the class at the bottom and then populates the data. But at the same time, you can also see that although we can actually generate a Person class and fill each of its attributes with values, the generated data is simply generated based on the type, such as the age field is filled with 5863. If the data has real meaning, randomness without rules can easily lead to mistakes. To solve this problem, we need to limit the scope of random data, which can be achieved through its configuration function.

Using random Configuration

    @Test
    public void testJavaBeanWithConfig(a) {

        MockConfig mockConfig =
                new MockConfig()
                        .subConfig("age")
                        // Set the range of int
                        .intRange(1.100)
                        .subConfig("email")
                        // Sets the generated mailbox re
                        .stringRegex("[a - z0-9] {5, 15} {3, 5} \ \ @ \ \ w \ \ [a-z] {2, 3}")
                        .globalConfig();

        Person mock = JMockData.mock(Person.class, mockConfig);
        System.out.println(mock);
    }
Copy the code

The results
Person[address=hXttj2s,age=2,email=w14hnn@UvFB9.kt,idCard=V5bBdX,name=KM8]
Copy the code

As you can see, age and email are already normal, so you can use its powerful configuration function to limit the generation of data. However, you can also find that for some data with simple boundaries, this can be done. Otherwise, it is difficult to generate data such as address and name with simple rules. For real-world data generation, the Java-FAker framework can be used.

Java-faker

Rely on

<dependency>
    <groupId>com.github.javafaker</groupId>
    <artifactId>javafaker</artifactId>
    <version>1.0.2</version>
</dependency>
Copy the code

The data generated

    @Test
    public void testRandomName(a) {
        Faker faker = new Faker();
        final Name name = faker.name();
        System.out.println("firstName : " + name.firstName());
        System.out.println("username : " + name.username());
        System.out.println("bloodGroup : " + name.bloodGroup());
        System.out.println("suffix : " + name.suffix());
        System.out.println("title : " + name.title());
        System.out.println("lastName : " + name.lastName());
        System.out.println("nameWithMiddle : " + name.nameWithMiddle());
        System.out.println("fullName : " + name.fullName());
        System.out.println("name : " + name.name());
        System.out.println("prefix : " + name.prefix());
    }
Copy the code

Generate results
firstName : Hollis
username : cristy.white
bloodGroup : O-
suffix : Sr.
title : Product Implementation Specialist
lastName : Johnston
nameWithMiddle : Alesia Hagenes Kiehn
fullName : Dr. Pat Marvin
name : Ms. Jamal Rau
prefix : Mr.
Copy the code

As you can see, Java-FAker is particularly convenient for generating data in the following basic format:

        Faker faker = new Faker();
        final Xx xx = faker.xx();
		xx.yyyy;
Copy the code

Steps:

  1. Create faker objects
  2. Get the entity object to be generated from the FAker object
  3. Call the entity object to get the generated part

Here, the entity object corresponds to the name above, which means that we need to generate the data related to the name. Once we get the entity object, we can only get part of the data, such as the first or last name in the name, prefix, and even blood type, which can be said to be very comprehensive. In addition, java-FAker supports many special entity objects, as follows:

  • Address
  • Ancient
  • Animal
  • App
  • Aqua Teen Hunger Force
  • Artist
  • Avatar
  • Back To The Future
  • Aviation
  • Basketball
  • Beer
  • Bojack Horseman
  • Book
  • Bool
  • Business
  • ChuckNorris
  • Cat
  • Code
  • Coin
  • Color
  • Commerce
  • Company
  • Crypto
  • DateAndTime
  • Demographic
  • Disease
  • Dog
  • DragonBall
  • Dune
  • Educator
  • Esports
  • File
  • Finance
  • Food
  • Friends
  • FunnyName
  • GameOfThrones
  • Gender
  • Hacker
  • HarryPotter
  • Hipster
  • HitchhikersGuideToTheGalaxy
  • Hobbit
  • HowIMetYourMother
  • IdNumber
  • Internet
  • Job
  • Kaamelott
  • LeagueOfLegends
  • Lebowski
  • LordOfTheRings
  • Lorem
  • Matz
  • Music
  • Name
  • Nation
  • Number
  • Options
  • Overwatch
  • PhoneNumber
  • Pokemon
  • Princess Bride
  • Relationship Terms
  • RickAndMorty
  • Robin
  • RockBand
  • Shakespeare
  • SlackEmoji
  • Space
  • StarTrek
  • Stock
  • Superhero
  • Team
  • TwinPeaks
  • University
  • Weather
  • Witcher
  • Yoda
  • Zelda

From id card to name to address, animal, book, profile picture, position and so on, basically cover every aspect of our life page. In addition, Java-FAker is more intimate to help us realize internationalization. Maybe we just saw the example of name, some friends think this framework is nice but not easy to use. Take the generation of name as an example, it is Johnston, Tom, Kiwi and other English names, and these data are rarely used in China. Java-faker already takes this into account. And it only takes one line of code to change.

The modified code
		// Faker Faker = new Faker();
		/ / the new code
        Faker faker = new Faker(Locale.CHINA);
        final Name name = faker.name();
        System.out.println("firstName : " + name.firstName());
        System.out.println("username : " + name.username());
        System.out.println("bloodGroup : " + name.bloodGroup());
        System.out.println("suffix : " + name.suffix());
        System.out.println("title : " + name.title());
        System.out.println("lastName : " + name.lastName());
        System.out.println("nameWithMiddle : " + name.nameWithMiddle());
        System.out.println("fullName : " + name.fullName());
        System.out.println("name : " + name.name());
        System.out.println("prefix : " + name.prefix());
Copy the code

Generate results
FirstName: Yitong USERNAME: Yilin. Dragon bloodGroup: A-suffix: IV Title: Investor Division Engineer lastName: Fan nameWithMiddle: Hu Si fullName: Meng Hongtao Name: Prefix: MissCopy the code

Just take the previous Faker Faker = new Faker(); Change to Faker Faker = new Faker(locale.china); Can. If you want to generate content from other countries, java-Faker supports the following countries:

  • bg
  • ca
  • ca-CAT
  • da-DK
  • de
  • de-AT
  • de-CH
  • en
  • en-AU
  • en-au-ocker
  • en-BORK
  • en-CA
  • en-GB
  • en-IND
  • en-MS
  • en-NEP
  • en-NG
  • en-NZ
  • en-PAK
  • en-SG
  • en-UG
  • en-US
  • en-ZA
  • es
  • es-MX
  • fa
  • fi-FI
  • fr
  • he
  • hu
  • in-ID
  • it
  • ja
  • ko
  • nb-NO
  • nl
  • pl
  • pt
  • pt-BR
  • ru
  • sk
  • sv
  • sv-SE
  • tr
  • uk
  • vi
  • zh-CN
  • zh-TW





conclusion

JmockData

Personally, I think it is the Random class of plus version, which is convenient to simply generate data according to type and can also be generated with their own configuration and rules. However, as mentioned above, the generated data does not have much practical significance. Simple data is ok, but it is not suitable for data with practical significance such as name and address.

Java-faker

Java-faker is actually a migration from the well-known Faker in Ruby. Many languages have their migration equivalents, such as Python and Java. So the amount of data and functionality is very sophisticated and proven, and very easy to use. In practical work, it can be optimized. If you want to talk about the shortcomings, I think some of his international is not comprehensive, such as license plate, ID card and so on. If you are more stringent with this data, I recommend another project, Yindz/Common-Random: an easy-to-use random data generator. This project has done a lot of processing for localized data, which is basically enough.