6

I have a method which builds an object and returns it.

The object as UUID as one of its fields. While building the object, random UUID is generated. Here is the code:

public MetaData getMetaData(String id) {
  return MetaData.newBuilder().setId(id)
    .setCorrelationId(UUID.randomUUID().toString())
    .setCreatedAt(now(UTC).format(ISO_ZONED_DATE_TIME))
    .build();
}

Here is my test:

@Test
public void shouldVerifyIfTheMetaDataIsBuild() {

  MetaData metaData = handler.getMetaData("1234");

  assertThat(metaData.getId(), is("1234"));
  assertThat(metaData.getCorrelationId(), isNotNull());
}

I'm just verifying if the correlationId is not null or not. Is there a better way to verify the UUID?

Manav
  • 553
  • 7
  • 18
Thiru
  • 2,541
  • 4
  • 25
  • 39
  • Seems like you don't want to do static mocking. In that case it can be enough to check that it is not blank, or maybe that it has the length of a UUID string, etc. – ernest_k Jul 16 '18 at 07:35
  • Yeah. I dont want to do static mocking – Thiru Jul 16 '18 at 07:37

6 Answers6

7

The only way to verify the current production code is to, yes, check that CorrelationId is not null. You could also check that the layout of the expected string matches a valid UUID string.

Of course, when you want to a bit of better checking, then you simply have to replace UUID.randomUUID().toString() with something that you can control.

For example you could create a UUIDGenerator interface, with a default method that creates a random UUID, as shown in your code. But in your test setup, you instead provide an implementation of that interface that returns a specific UUID.

Then your test code could know which UUID should be used, and assertThat(actualUuid, is(expectedUuid)).

GhostCat
  • 137,827
  • 25
  • 176
  • 248
6

I would change this line:

assertThat(metaData.getCorrelationId().toString(), isNotNull());

to the following:

assertThat(metaData.getCorrelationId(), isNotNull());

otherwise you would get a NullPointerException if metaData.getCorrelationId() returns null instead of an assertion failure.

Additionally, you could test if metaData.getCorrelationId() returns a string that represents a valid UUID, by trying to parse it:

try {
    UUID.fromString(metaData.getCorrelationID());
} catch (IllegalArgumentException e) {
    fail("Correlation ID is not a valid UUID: " + metaData.getCorrelationId());
}
Jesper
  • 202,709
  • 46
  • 318
  • 350
3

When using a UUID, I check the String pattern using a regex.

assertTrue(id.matches(Pattern("([a-f0-9]{8}(-[a-f0-9]{4}){4}[a-f0-9]{8})")))

This way I check if it is present and if the String is indeed a UUID as I had it happen that an unintended change put a space there which would pass in the assertNotNull solutions.

Koen Prins
  • 71
  • 3
  • More apt way to match the Pattern in java is `Pattern.matches("([a-f0-9]{8}(-[a-f0-9]{4}){4}[a-f0-9]{8})", metaData.getCorrelationID());` – Faraz Jul 29 '21 at 23:49
1

One more thing you can validate about UUID is it's length (as it is always 36 java.util.UUID.randomUUID().toString() length).

There will be a chance for detecting changes in implementation in future.

staszko032
  • 802
  • 6
  • 16
1

I added a UUID validator to Apache Commons Validator. It's not yet been merged, but you can vote for it here: https://github.com/apache/commons-validator/pull/68

Daniel Heid
  • 199
  • 1
  • 5
0

As rightly said by @GhostCat, since we don't have control over UUID.randomUUID(), the only way would be to check if the UUID generated is not null. For that, you may use the code below:

assertNotNull(metaData.getCorrelationId());
Pang
  • 9,564
  • 146
  • 81
  • 122
Madhu Bhat
  • 13,559
  • 2
  • 38
  • 54