Random Values in the Unit Tests of Java with Podam

In this article I will show how to write random values in the unit tests of Java with Podam. Podam is a library to write random values in all the fields of an input object to the services to test.

Content:

  • The Podam Factory
  • Exclusions
  • Custom Strategies
  • Maps and Lists

For more details, check this video.

All the code is available in this repository.

The Podam Factory

Podam is a dependency that will write content for you. I use it very often when writing unit tests. First, I split my unit test into the given-when-then parts. And in the given part I instantiate my input data. Nevertheless, sometimes my input data tends to be big and long. I have some objects which have plenty of fields and it’s boring to set a dummy value to each field. Here comes Podam.

With Podam I specify which object I want to fill with the dummy data and Podam will check the data type of each field, set a random value and create the final object. Let’s start by adding the maven dependency.

        <dependency>
            <groupId>uk.co.jemos.podam</groupId>
            <artifactId>podam</artifactId>
            <version>7.2.5.RELEASE</version>
        </dependency>

Now, in the @BeforeAll, I built the factory. The factory contains the rules to build an object.

    private static PodamFactory podamFactory;

    @BeforeAll
    public static void setUp() {
        podamFactory = new PodamFactoryImpl();
    }

Now from my test, I indicate which object I want to build, put it as an input parameter to the factory, and let the Podam factory build the object. Podam will call the constructor and the setters to fill all the available data.

    @Test
    void testUserMapper() {
        // given
        User user = podamFactory.manufacturePojo(User.class);

        // when
        UserDto userDto = mapper.toUserDto(user);

        // then
        assertAll(
                () -> {
                    assertEquals(user.getFirstName(), userDto.getFirstName());
                    assertEquals(user.getLastName(), userDto.getLastName());
                }
        );
    }

Ok, with this, my unit tests still work. But what’s the content of my object now?

Random value generated by Podam
Random value generated by Podam

Whoa! When it says it’s random data, I’ve never imagined that random data. But my application should work even with that, which is the case.

I should have some JavaX constraints to have a limit on the name’s length. It can work with @Size or with @Max or even with @Min if you want.

Exclusions

Let’s go now with the image object, where I have a URL to set. The point here is that the URL, the path, is stored in plain text. And Podam doesn’t know it’s a URL, it’s a path. And it will generate a random text. So first I want to ignore this fill and set it manually. For that, I will add the following annotation.

    @PodamExclude
    private String path;

This way, Podam will exclude this field when generating the object. Now I can set it the way I want.

Custom Strategies

But what if I use Podam to write random strings which looks like a URL? I will create my custom pattern strategy to indicate to Podam how to fill this field.

public class URLStringStrategy implements AttributeStrategy<String> {
    @Override
    public String getValue(Class<?> aClass, List<Annotation> list) {
        return "/one/two/three";
    }
}

The strategy must implement AttributeStrategy and return me a string. Now I have the value returned from my strategy. And in the implementation, I can return whatever I want.

    @PodamStrategyValue(URLStringStrategy.class)
    private String path;

Maps and Lists

One last point. What happens with lists or maps? Will Podam create an empty list or an empty map? Will Podam create one item? Or how much? In fact, Podam will create a random number of elements for the lists and maps. With random values depending on the type of the elements. But what if I want a specific number of elements?

    @PodamCollection(nbrElements = 10)
    private List<Message> messages;

This way, Podam will create up to 10 elements of the message object. And for the message object, it will look at each field and set it randomly. It won’t only create random values for the current object but also for the children objects.

I use Podam a lot on many projects where I have to build complicated objects for testing. I may have problems if I only use fixed values. I may not test the length limits, the size limits for lists, dates which are far away or in the past. As Podam injects random values for the objects, I must be prepared for anything. I may even run the tests several times to be sure that all the extreme values are tested almost once.

References

Repository

My New ebook, How to Master Git With 20 Commands, is available now.

Leave a comment

A WordPress.com Website.