Reputation: 15179
I have a very old cucumber-java project (v. 1.2.2) that I'm trying to update to use the current version (6.10.4). For the most part it's going well, but I'm having trouble converting an old step definition which used the @Delimiter
annotation to use a custom parameter type.
This was the old step definition using the delimiter:
@Then("^there are error messages: \"(.*)\"$")
public void assertAllMessages(@Delimiter("; ") List<String> messages) throws Exception {
// ...
}
Since @Delimiter
was removed when XStream support was removed from cucumber-java, the documentation says to replace it with a custom @ParameterType
. Fair enough. I wrote this one, which should be sufficient to identify a string representation of a semi-colon-separated list and convert it to a List<String>
:
@ParameterType("(?:.+;)+.+")
public List<String> stringList(String raw) {
String[] values = raw.split(";");
return Arrays.asList(values);
}
And then I removed the @Delimiter
from the step definition, but left it otherwise as-is.
However when I run my test, it fails and indicates that I should register a parameter type for List:
Caused by: java.lang.IllegalArgumentException: Can't transform 'foo; bar; baz' to java.util.List<java.lang.String>
BuiltInParameterTransformer only supports a limited number of class types
Consider using a different object mapper or register a parameter type for java.util.List<java.lang.String>
at io.cucumber.cucumberexpressions.BuiltInParameterTransformer.createIllegalArgumentException(BuiltInParameterTransformer.java:114)
at io.cucumber.cucumberexpressions.BuiltInParameterTransformer.doTransform(BuiltInParameterTransformer.java:33)
at io.cucumber.cucumberexpressions.BuiltInParameterTransformer.transform(BuiltInParameterTransformer.java:22)
at io.cucumber.cucumberexpressions.RegularExpression.lambda$match$0(RegularExpression.java:66)
at io.cucumber.cucumberexpressions.ParameterType$TransformerAdaptor.transform(ParameterType.java:268)
at io.cucumber.cucumberexpressions.ParameterType.transform(ParameterType.java:233)
... 47 more
I know that it has successfully picked up my custom parameter type, because it's in the same file as the step definition. (Further if I create another copy elsewhere in the glue directory, it complains there's already a parameter type named "stringList" registered.)
I also tried changing the regex to just @ParameterType(".*")
, but it made no difference.
How do I get Cucumber to use my custom parameter type for converting a string into a List<String>
?
Upvotes: 6
Views: 12170
Reputation: 8676
Assume you have this feature file:
Feature: test
Scenario: test scenario
Given: This string: foo; bar; baz
So, to have a proper use of custom parameter types you have to assure two things:
@Given("This string: {list}")
public void givenThisString(List<String> myList){
System.out.println(myList);
}
@ParameterType("([^;]+);?")
public List<String> list(String[] vals){
return Arrays.asList(vals);
}
Put your attention at that in your step definition you refer to parameter type as {list}
so that Cucumber knows where to take a parser. If you do not specify type name explicitly through annotation value, Cucumber takes the type name as the name of a method you have annotated with @ParameterType
Upvotes: 2
Reputation: 6036
Feature-file. Delimiter is ";". Examples with and without spaces.
Feature: List of strings testing
Scenario:
Given a list of names Anna; Ken; Oleg; Piter
Given a list of names Anna;Ken;Oleg;Piter
Given a list of names Anna; Ken ; Oleg; Piter
Steps:
@Given("a list of names {names}")
public void getListOfNames(List<String> names) {
for (String n : names) {
System.out.println("|" + n + "|");
}
}
@ParameterType(".*")
public List<String> names(String s){
return Arrays.asList(s.split("\\s*;\\s*"));
}
Cucumber version: 7.18.0
Upvotes: 0
Reputation: 12039
Parameter types are part of cucumber-expressions. So instead of writing a regex you should either use a cucumber-expression or use the exact regex from the parameter type in your regular expression.
@ParameterType("(?:.+;)+.+")
public List<String> stringList(String raw) {
String[] values = raw.split(";");
return Arrays.asList(values);
}
@Then("there are error messages: \"{stringList}\"")
public void assertAllMessages(@Delimiter("; ") List<String> messages) throws Exception {
// ...
}
Upvotes: 1