How I enhanced my project by generating custom fake data with Dummy4j

featured image

Most fake data providers offer a wide variety of default generators and the ability to add custom definitions to them. However, ease of customization is not always a top priority in their architecture. Fortunately, one of the most important features of Dummy4j is the ability to easily extend the generator and provide custom definitions.

The kind of custom data I needed to generate

Dummy4j offers many generators, e.g. ColorDummy, FinanceDummy or NameDummy, that allow us to easily create fake data with a single line of code, like in the following code snippet:

In my example project, I want to get random fake data that are not included in Dummy4j – a list of cookie flavours.

The ways of customizing Dummy4j

First, we can simply add a new yaml file with custom definitions and manually resolve a key every time we need a flavour, like below:

Going a step further, we can create our CustomDummy that extends Dummy4j. Thanks to that we can:

  • gain more control over our fake data,
  • unit test our extensions,
  • add as many new definitions as we want without cluttering the code,
  • still keep all the default functionality.

In this article, I’m going to describe the latter approach. I’m going to extend Dummy4j, enhance it with a new FlavourDummy and generate custom data as simply as on this code snippet:

How I have modified my project

For this article I use the changes I’ve introduced in my jwt-spring-boot-angular-scaffolding project as an example. The project allows for an authorised user to view a list of cookies and is a simple scaffolding to demonstrate the authorisation process. I wanted to remove hard coded flavours from the CookieController and make my code more clean.

Before using Dummy4j in the project, all flavours were generated with the following naïve code:

After adding the Dummy4j library and providing an abstraction for a repository, the controller looks like this:

Below I’m going to describe how I created my CustomDummy and used it in the CookieJar implementation – the RandomCookieJar class. All files are linked to their location in the repository so you can easily find the complete code. You can see the new files I added to the project on the following screenshot:

custom fake cookie data files in the project directory

You can find all those changes in the 15eb8da0e539d945ecd272f539dddf02aed18fd3 commit.

Adding Dummy4j and custom definitions for fake data

First of all, we have to add the dummy4j maven dependency to our pom.xml file (visit the maven repository for the latest version):

Secondly, we need to put the flavour.yml file in the resources/dummy4j directory, where Dummy4j looks for definitions by default:

Extending Dummy4j

Our end goal is to create a CustomDummy that serves the same dummies as the original Dummy4j plus the additional FlavourDummy. In order to achieve this, we need to:

  • extend the Dummy4j class (line 5),
  • initialize the flavourDummy object in the CustomDummy constructor (line 10),
  • write a public method that returns the FlavourDummy instance (line 13).

As a result, once we initialize the CustomDummy class, we’ll be able to reach all FlavourDummy methods by calling:

This allows us to hide implementation details of the FlavourDummy methods and to use our new dummy just like all other dummies that the library provides by default.

Implementing the FlavourDummy methods

The FlavourDummy constructor receives the CustomDummy instance thus giving it the whole set of Dummy4j methods to use. Therefore, we can use Dummy4j’s ExpressionResolver to get a random value for the definition key. In the example below I’m only implementing a method for getting a random mixed flavour:

Unit testing the solution

We need to verify if the flavours will be returned properly, as well as document the expected behaviour. For this reason I’m going to create the FlavourDummyTest class and add the following unit test:

Using the data provider across an application

The custom dummy works in my unit tests. However, we need to actually use it to send the flavours in an API response.

Creating a contract for the data provider

We want to use our custom fake data generator as a substitute for a real repository. To minimize the impact on the code when we switch to the production data source, we may want to create an interface that both the fake and production repository have to implement:

Implementing the contract in the fake repository

Next, we can implement the interface in the RandomCookieJar class and provide 10 cookies with random flavours:

We enclosed the details of generating randomly mixed flavours in the FlavourDummy class. What’s more, we hid the fake repository under the CookieJar interface. As a result, our CookieController will know nothing about how it gets the data.

Injecting the fake repository

Finally, we can inject our fake repository to the controller. For this purpose we can configure the following Bean:

In case we have to replace the fake repository with a production one, we can simply replace the returned value with a proper CookieJar implementation.

As a result, we can inject the repository to the CookieController in the way you could see in the beginning of this article:

In the end, we can verify the results by running the application, adding a user, and logging in to see 10 random cookies:

custom fake data in the cookie list

More on generating custom fake data

Photo by Nattawara . from Pexels

Leave a Reply

Your email address will not be published. Required fields are marked *