One of the most tedious task when writing test class is to create test data with no particular requisites. The idea is to have a helper method that is able to return the object given a map of field-values pairs. This should be easily customisable in order to have default values that can be overridden by provided field-values pairs.

I've thought writing something like this:

public static MyCustomObject__c createMyCustomObject(Map<Schema.SObjectField, String> fieldValueMap) {
    Map<String, Schema.SObjectField> fieldMap = Schema.getGlobalDescribe().get('MyCustomObject__c').getDescribe().fields.getMap();

    Map<Schema.SObjectField, String> defaultFieldValueMap = new MapMap<Schema.SObjectField, String>();
    // Populate the default field map here

    MyCustomObject__c o = new MyCustomObject__c();
    for (Schema.SObjectField field : fieldMap.values()) {
        if (fieldValueMap.containsKey(field)) {
            o.put(field, fieldValueMap.get(field));
        } else if (defaultFieldValueMap.containsKey(field)) {
            o.put(field, defaultFieldValueMap.get(field));

    return o;

I think that the main problem is the types I choose for the field-value maps: if the field type isn't compatible with the type String it throws an error. Could anyone suggest a workaround for this? Even a different approach would be appreciated.

The main requisites of this helper methods are:

  • It should not perform any DML operation.
  • It should accept an arbitrary number of field-value pairs. My idea use a maps but anything is good if it works.
  • It should handle default field-value pairs. They could either be defined as attributes of the class or inside the method.
  • It should return the object.

I would recommend creating a test data factory. It is essentially just an entire class dedicated to creating the base objects that are needed for almost every apex function (accounts, contacts, cases, etc.)


You can create the method to return a map if you need certain values or you can just have the method insert the records and return void then query for them in each test class once you have called the method to insert them.

| improve this answer | |
  • Yeah, my point is exactly that. I what the helper function to make the process of creating test data easier. What makes my request different from the code linked in your answer and the ones posted in the documentation is that I want to make it possible to pass different values for different fields and make none of them mandatory. Unfortunately, the only practical way to achieve an arbitrary number of parameters is to pass them as map. – gvgramazio May 14 '19 at 15:52
  • I could pass a map for each primitive data type but it's simply ugly and awkward. I could also try to cast the string value as the primitive data type compatible with the current SObjectField inside the for loop. However, I don't know how to get the primitive data type given an SObjectField. – gvgramazio May 14 '19 at 15:57
  • If you are already having to pass in different values and field names it sounds like more work to do it this way rather than just having base objects (from testdatafactory) and querying for them then setting the fields in each test class. – Logie C May 14 '19 at 16:07
  • Querying them and then setting the field in each class means that I previously inserted them that is not what I want in this case for several reasons like triggers, validation rules and dml operation itself. – gvgramazio May 14 '19 at 16:17
  • I've updated the question specifying which requirements the helper method should met. – gvgramazio May 14 '19 at 16:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.