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

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
  • DateConverter
  • ExamplesTableConverter

Custom parameter converters

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 provides a DateConverter backed up with a SimpleDateFormat with format dd/MM/yyyy. To configure the use of aDateConverter with a different date pattern:

    public MyStory() {
        useConfiguration(new MostUseflConfiguration()
            .useParameterConverters(new ParameterConverters()
               .addConverter(new DateConverter(new SimpleDateFormat("yyyy-MM-dd")))));  // date converter with custom date pattern
    }

Annotated methods as parameter converters

In some cases defining the converter in Configuration is not an option as the conversion is much more dynamical in nature. In this case, one can annotated Steps method to act as parameter converters when annotated by @AsParameterConverter:

    public MySteps() {
        // Method used as dynamical parameter converter
        @AsParameterConverter
        public Trader createTrader(String name){
            return mockTradePersister().retrieveTrader(name);
        }
    
        private TraderPersister mockTradePersister() {
            return new TraderPersister(new Trader("Mauro", asList(new Stock("STK1",
                10.d))));
        }

    }

The parameter converter configuration is done in the AbstractStepsFactory so you can use any implementation of InjectableStepsFactory that extends the abstract implementation, e.g.:

    public MyStory() {
        addSteps(new InstanceStepsFactory(configuration(), new MySteps()).createCandidateSteps());
    }