1

Let's say there is a step in Cucumber scenario step which uses data table:

And I add a new user

 | firstName | lastName | workEmail        | workPhone      | userName | assignedRoles       | assignedAdvisorCodes |
    | Steven    | Gerrard  | steeveg@test.com | 12312312346345 | steeveg  | Advisor,Compliance  | 1107,1108            |

then step definition will look like

@And("^I add a new user$")

public void i_add_a_new_user(List<User> users) {

The gist is that 'User' POJO contains fields of type Collection:

public class User {
    private Set<String> assignedRoles;
    private Set<String> assignedAdvisorCodes;

and I expected these fields to be populated with what I've specified in cucumber data table delimited with comma.

=================

So, my issue is that 'user' object in List will got assigned all fields from data table except for assignedRoles and assignedAdvisorCodes since both of them are of type Set (actually it does not matter, it could have been anything of Collection type).

please suggest how to overcome this. I use cucumber 2.4.0 but have not found any solution even for version 3+. It's clear how to deal with object having fields if primitive or class data types but NOT with fields of type Collection.

Community
  • 1
  • 1
vitali_li
  • 101
  • 1
  • 2
  • 13

2 Answers2

1

In Cucumber version 2.4.0 one can use XStream custom transformation.

public class SetStringConverter implements Converter{

    @Override
    public boolean canConvert(Class arg0) {
        return Set.class.isAssignableFrom(arg0);
    }

    @Override
    public void marshal(Object arg0, HierarchicalStreamWriter arg1, MarshallingContext arg2) {

    }

    @Override
    public Object unmarshal(HierarchicalStreamReader arg0, UnmarshallingContext arg1) {
        return  new HashSet<String>(Arrays.asList(arg0.getValue().split(",")));
    }
}

There are two ways to declare this for XStream to use. First, one can declare it inside the POJO. This is the better way to use.

@XStreamConverter(value = SetStringConverter.class)
private Set<String> assignedRoles;
@XStreamConverter(value = SetStringConverter.class)
private Set<String> assignedAdvisorCodes;

Else one can declare them globally on the runner. Then no need to declare on POJO.

@XStreamConverters({
    @XStreamConverter(value = SetStringConverter.class)
})
public class RunCucumberTest {
}

In Cucumber version 3 and above XStream is gone. The below class is unique in the project and needs to be available in the declared glue path.

public class Configurer implements TypeRegistryConfigurer {

    @Override
    public void configureTypeRegistry(TypeRegistry registry) {

        registry.defineDataTableType(new DataTableType(User.class, new TableEntryTransformer<User>() {
            @Override
            public User transform(Map<String, String> entry) {
                return User.createUser(entry);
            }
        }));
    }

    @Override
    public Locale locale() {
        return Locale.ENGLISH;
    }
}

In User POJO u will need to add the createUser method.

public static User createUser(Map<String, String> entry) {
        User user = new User();
        user.firstName = entry.get("firstName");
        user.lastName = entry.get("lastName");
        user.assignedRoles = new HashSet<String>(Arrays.asList(entry.get("assignedRoles").split(",")));
        user.assignedAdvisorCodes = new HashSet<String>(Arrays.asList(entry.get("assignedAdvisorCodes").split(",")));
        return user;
    }
Grasshopper
  • 8,908
  • 2
  • 17
  • 32
0

If you use gherkin with qaf it is supported. You need to provide data table as below:

 And I add a new user
 | firstName | lastName | workEmail        | workPhone      | userName | assignedRoles       | assignedAdvisorCodes |
 | Steven    | Gerrard  | steeveg@test.com | 12312312346345 | steeveg  | [Advisor,Compliance]| [1107,1108]          |

In case of cucumber you need to provide transformer as @Grasshopper provided in answer.

user861594
  • 5,733
  • 3
  • 29
  • 45