EasyTest : Understanding Converters Support

Anuj Kumar edited this page Jun 20, 2013 · 8 revisions

EasyTest not only gives you the facility to pass input parameters to your test methods, it also provides you with various mechanisms to pass the objects of your choice as input parameters and not just Java types.

In this WIKI discussion, we will learn how we can pass a complex object as input parameter to a method that is run with EasyTest Framework.

Lets look at an example where I have a complex Object that I want to pass as parameter to my test method.

Here is an (almost) complete example of how you can do that.

 @RunWith(DataDrivenTestRunner.class)
 @DataLoader(filePaths={"xmlBasedData.xml"} , loaderType= LoaderType.XML)
 public class EasyTestConverterExample {

private ItemService testSubject;

@Before
public void setUp() {
    testSubject = new MockItemService();
}


@Test
public void getItemsData(Item item){
    System.out.println("Item is" + item);
    Item searchedItem = testSubject.findItem(item.getItemId());
    Assert.assertNotNull(searchedItem);
    Assert.assertEquals(item.getItemId(), searchedItem.getItemId());
}

Thus I have a test method that takes as input an Item Object. Lets look at what exactly this item object contains :

public class Item {

private String description;

private String itemType;

private ItemId itemId;

/**
 * @return the description
 */
public String getDescription() {
    return description;
}

/**
 * @param description the description to set
 */
public void setDescription(String description) {
    this.description = description;
}

/**
 * @return the itemType
 */
public String getItemType() {
    return itemType;
}

/**
 * @param itemType the itemType to set
 */
public void setItemType(String itemType) {
    this.itemType = itemType;
}



public ItemId getItemId() {
    return itemId;
}

public void setItemId(ItemId itemId) {
    this.itemId = itemId;
}


@Override
public String toString() {
    return "Item [description=" + description + ", itemType=" + itemType + ", itemId=" + itemId + ""
        + "]";
}

Thus in short its a complex object. How can we pass this complex object as parameter to our test method. Theres a two step process to it:

  • Define a Converter that can convert the data from a Map of key value pair to an Item Object,
  • Register the converter with the EasyTest framework. You can register the converter using @Convertes annotation at the method or class level or can directly register in the BeforeClass annotated method just like PropertyEditor registration.

So lets see how we can define a Converter. In order to define your custom Converter, you have to extend the AbstractConverter class of EasyTest Framework and override the convert method. Since it is isolated from your test cases, it is fine to extend an external class.

Here's the sample code :

public class ItemConverter extends AbstractConverter<Item> {

@Override
public Item convert(Map<String, Object> convertFrom) {
    Item item = null;

    if (convertFrom != null) {
        item = new Item();
        item.setDescription((String) convertFrom.get("itemDescription"));
        ItemId itemId = new ItemId(Long.valueOf((String) convertFrom.get("itemId")));
        item.setItemType((String) convertFrom.get("itemType"));
    }
    return item;
}

  }

So, lets try to understand what's happening here. The first thing to notice here is that the convert method has as its input parameter a Map of String, Object. This map actually represents the key value pair of the input test data that your particular method requires. Thus, all you have to do is call a get on this map against the keys that represent the Item data and create your item object.

I know you might ask this: If I have defined 10 sets of test data for my Test method, how does EasyTest know with what data to instantiate the Item object with and what if it fills in incorrect data?

Well, the answer is simple. EasyTest knows when to call this converter with exactly which data set and thus there is no chance of it being incorrect. Thus if you have a test method with 1o different input data sets, then EasyTest framework will call the Convert method for each of these input data sets. Thus you define a generic converter and rest all is taken care of by the EasyTest Framework.

Next in line is how to tell the EasyTEst Framework about this Converter being available. The answer is, just the same way we register Property Editors, we can register Converters as well. Thus for the above case, the complete test class would be:

@RunWith(DataDrivenTestRunner.class)
@DataLoader(filePaths={"classpath:xmlBasedData.xml"} , loaderType= LoaderType.XML)
@Converters({ItemConverter.class})
public class EasyTestConverterExample {

private ItemService testSubject;

@Before
public void setUp() {
    testSubject = new MockItemService();
}

@Test
public void getItemsData(Item item){
    System.out.println("Item is" + item);
    Item searchedItem = testSubject.findItem(item.getItemId());
    Assert.assertNotNull(searchedItem);
    Assert.assertEquals(item.getItemId(), searchedItem.getItemId());
}

}

As you can see we have registered the converter using @Converters annotation at the class level. We can also use this annotation at the method level.

If you don't want to use @Converters annotation for some reason, you can then use the standard support of registering the converters in the beforeclass annotated methods:

 @BeforeClass
 public static void setup(){
    ConverterManager.registerConverter(ItemConverter.class);
 }

As you can see, we have registered the Converter using the ConverterManager class's registerConverter method inside the method annotated with @BeforeClass.

And thats all you have to do.

In case you have any questions or queries regarding Converters or any other functionality of EasyTest, do open an issue or write to anujkumar@easetech.org

Happy EasyTest(ing)