Parameter Converters

Build-in support for Java types and Lists

JBehave automatically converts the textual representation of a parameter extracted from the candidate step with the parameter type of the matched method in the Steps class. Let's go back to our example to make this point clear. Consider a single textual step:

    Given a stock of symbol STK1 and a threshold of 10.0

which we map to the Java method:

    @Given("a stock of symbol $symbol and a threshold of $threshold")
    public void aStock(String symbol, double threshold) {
        // ...
    }

The two arguments which are identified as parameters in matching the textual step to the annotation pattern are: "STK1" and "1.0". These are converted respectively to a String and a double.

If we had comma-separated values, e.g

    Given a stock of symbols STK1,STK2 and thresholds of 10.0,20.0

these would handled automatically as well, provided the type of the parameter was a List

    @Given("a stock of symbols $symbols and thresholds $thresholds")
    public void aStock(List symbols, List thresholds) {
        // ...
    }

More in general, JBehave provides out-of-the-box support for Strings, numbers and the lists thereof.

ParameterConverter interface

At the core of the parameter conversion mechanism lies the ParameterConverters facade and the interface:

public static interface ParameterConverter {
 
  boolean accept(Type type);
 
  Object convertValue(String value, Type type);
 
}

The built-in support for Java types is provided by implementations of this interface. Specifically:

  • NumberConverter
  • NumberListConverter
  • StringListConverter

Support for custom parameter converters

This mechanism then allows for custom converters to be defined too. For example, let's consider the case of date conversion, a rather common one. The step would typically look like:

    When a stock of symbol STK1 is traded on 09/09/2009

and the matching step is

    @When("a stock of symbol $symbol is traded on $tradedOn")
    public void aStockIsTradedOn(String symbol, Date tradedOn) {
        // ...
    }

Out of the box, JBehave cannot know how to convert the argument value "09/09/2009" to a Date object. Date formats are far from standard. In this case, we want to use the date format "dd/MM/yyyy" and configure the parameter converter for Date type. An implementation of Date converter, backed up a SimpleDateFormat, could be:

public class DateConverter implements ParameterConverter {

    private final SimpleDateFormat dateFormat;

	public DateConverter(String dateFormat) {
		this.dateFormat = new SimpleDateFormat(dateFormat);
    }

    public boolean accept(Type type) {
        if (type instanceof Class) {
            return Date.class.isAssignableFrom((Class) type);
        }
        return false;
    }

    public Object convertValue(String value, Type type) {
    	try {
			return dateFormat.parse(value);
		} catch (ParseException e) {
			throw new RuntimeException("Could not convert value "+value+" with format "+dateFormat.toPattern());
		}
    }

}

Then we configure the use of the newly defined DateConverter in our Steps class:

    private static final StepsConfiguration configuration = new StepsConfiguration();

    public MySteps(ClassLoader classLoader) {
        super(configuration);
        configuration.useParameterConverters(new ParameterConverters(
               new DateConverter("dd/MM/yyyy)));  // define converter for custom type Date
    }