Reputation: 1843
A fairly elementary question as I get used to Cucumber after a long hiatus and also get up to speed with Java 8 and lambdas. I wonder if someone can point out a better/optimal way of doing this simple Step Definition:
Given a Cucumber Scenario:
Scenario:Student submits grades
Given a student has completed a paper
When they have submitted the following grades
| math | good |
| physics | poor |
Then the grades website shows the correct grading
And data that needs to be sent to an api in the following format:
iteration 1:
math:good
iteration 2:
physics:poor
...before asserting in the Then
that both reports display as expected.
And the troublesome step definition:
@When("they have submitted the following grades")
public void theyHaveSubmittedTheFollowingGrades(Map<String, String> reportData) {
String reportData;
reportData.forEach((subject, grade) ->
report = String.join(subject, ":", grade));
sendReportGrades(report);
); //Unexpected token error here in IntelliJ
}
so sendReportGrades(report)
method calls the service that will apply the grade only if in subject:grade
format and it needs to send both reports (or however many are in the table).
Upvotes: 0
Views: 1202
Reputation: 86
I would use a POJO and dependency injection to make it more readable. Using Pico container or Spring for dependency injection as described here : https://cucumber.io/docs/cucumber/state/
In the Feature file (using a header in the data table of the When step) :
When they have submitted the following grades
| subject | grade |
| math | good |
| physics | poor |
POJO
public class ReportData {
private String subject;
private String grade;
public ReportData(String subject, String grade) {
this.subject = subject;
this.grade = grade;
}
@Override
public String toString() {
return String.format("%s:%s", subject, grade);
}
}
Step definition
@When("they have submitted the following grades")
public void theyHaveSubmittedTheFollowingGrades(List<ReportData> reportData) {
reportData.stream()
.map(ReportData::toString)
.forEach(r -> sendReportGrades(r));
}
private void sendReportGrades(String report) {
// Calling system under test
...
System.out.println("report sent -> " + report);
}
Before Cucumber 3.x, dependency injection from the data table into the POJO was using xstream so it was really plug-and-play, but since 3.x, you have to declare your mapping from the Data Table into the ReportData POJO class like this in your step definition class :
@DataTableType
public ReportData convert(Map<String, String> entry){
return new ReportData(
entry.get("subject"),
entry.get("grade")
);
}
It gives you :
report sent -> math:good
report sent -> physics:poor
Upvotes: 1
Reputation: 1891
What about
public void theyHaveSubmittedTheFollowingGrades(Map<String, String> reportData) {
reportData.forEach((subject, grade) -> sendReportGrades(String.join(subject, ":", grade)));
}
Upvotes: 1