Passing true null values from Gherkin

By default Gherkin is not able to pass an actual null value from a feature file to a step definition. The following sample allows you to do more than just that.

Passing a null value

Supports inverse test cases: what if a value is not provided. (At all, not even as an empty string)

Passing a UUID

Having the option to provide a guaranteed unique value always comes in handy.

Automatic application of prefix

Helps identify & automatically clean test objects and keeps repeating data out of feature files. The ~ MUST be the first character to be replaced with a prefix. If you need a prefix any where else, use [~]. This supports using prefixed names with leading whitespace characters.

How to use

When defining a scentence, use the {str} placeholder instead of the {string} place holder.

The code

Next to a Hooks step definition file, I also make use of a GenericSteps file. In this file is the following code:

private final Pattern prefixPattern = Pattern.compile("^~(.*)");
private final String prefix = "some_prefix";

@ParameterType("\"(?:\\\\\"|[^\"])*\"")
public String str(String str) {
    return this.stringType(str);
}

@DataTableType()
public String stringType(String cell) {
    // Return null for '[null]'
    if (cell == null || cell.contains("[null]")) {
        return null;
    }

    // Remove any surrounding double quotes: 
    // The entire variable as used in Gherkin, including quotes, is passed.
    cell = cell.replaceAll("^\"|\"$", "");

    // Replace any '[uuid]' with a UUID.
    cell = cell.replaceAll("(\\[uuid])", UUID.randomUUID().toString());

    // Apply test prefix
    Matcher matcher = this.prefixPattern.matcher(cell);

    if (matcher.find()) {
        cell = String.format("%s%s", this.prefix, matcher.group(1));
    }

    // When a `~` is needed as-is at the beginning of a string, it needs to be escaped.
    cell = cell.replace("\\~","~");
    // When a prefix insertion is needed somewhere else, use `[~]` as replacement token.
    // This comes in handy when, for example, needing to test with leading whitespace characters.
    cell = cell.replace("[~]", this.prefix);

    return cell;
}