[SalesForce] Apex Test Class for Inserting Both Parent and Child Objects

Can anyone help me create a test class for this? This apex class inserts both the parent (Custom_object1__c) and multiple child (Custom_Item__c) at the same time. The insertion depends first on the parent object's record types. Most of the topics I've seen focus more on inserting just one object, and I don't know how to insert another which is related to its parent.

Here's my apex controller:

public with sharing class MyCustomController {

    private ApexPages.StandardController con;
    public Custom_object1__c customobj {get;set;}
    public List<CustomWrapper> customlist {get;set;} 
    public Integer rowToRemove {get;set;}


    public List<User> userList {get; set;} 
    public String searchTerm {get; set;}
    public String selected {get; set;}
    public String acctname {get; set;} 
    public List <SelectOption> options {get; set;}
    public String selectedRT {get; set;}
    public Boolean form1 {get; set;}
    public Boolean form2 {get; set;} 
    public List<SelectOption> SelectValues {get; set;} 

    public MyCustomController(ApexPages.StandardController controller) {
        con = controller;
        this.customobj = (Custom_object1__c)controller.getRecord();

        form1 = form2 = false;
        selectedRT = '';

        expenselist = new List<CustomWrapper>();
        addNewRowToCustomList();
        if(customobj.Account__c != null) {
            Account accq = [SELECT ID, Name FROM Account WHERE ID =: customobj.Account__c];
            acctname = accq.Name;
        }

    }

    public void addNewRowToCustomList() {
        List<CustomWrapper> temp_customlist = new List<CustomWrapper>();
        CustomWrapper newRecord = new CustomWrapper();
        Custom_Item__c newCustomRecord = new Custom_Item__c();
        newRecord.cit = newCustomRecord;
        newRecord.index = temp_customlist.size();
        temp_customlist.add(newRecord);
        for(CustomWrapper cloop : temp_customlist) {
            customlist.add(cloop);
        }
    }

    public void removeRowFromCustomList() {
        List<CustomWrapper> rem_customlist = new List<CustomWrapper>();
        for(CustomWrapper cloop : customlist) {
            rem_customlist.add(cloop);
        }
        rem_customlist.remove(rowToRemove);
        customlist.clear();
        for(CustomWrapper culoop : rem_customlist) {
            customlist.add(culoop);
        }
    }

    Public PageReference cancel() {

        PageReference pageref = new PageReference('/home/home.jsp');
        pageref.setRedirect(true);
        return pageref;
    }

    public PageReference save() {

        List<CustomWrapper> co_customlist = new List<CustomWrapper>();
        List<Custom_Item__c > newCustomsList = new List<Custom_Item__c >();
        Decimal total = 0;
        for(CustomWrapper cloop : customlist) {
            co_customlist.add(cloop);
        }
        system.debug('co_customlist >> ' + co_customlist);
        for(CustomWrapper totalloop : co_customlist) {
            total += totalloop.cit.Amount__c;
            system.debug('totalu >> ' + total);
        }
        system.debug('totalb >> ' + total);
        Custom_object1__c co_custom = new Custom_object1__c();
        co_custom.User__c = selected;
        co_custom.Account__c = customobj.Account__c;
        co_custom.Employee__c = customobj.Employee__c;
        co_custom.Total__c = total;
        insert co_custom;


        if(co_customlist !=null && !co_customlist.isEmpty()) {

            for(CustomWrapper eachRecord : co_customlist) {
                Custom_Item__c cusTemp = new Custom_Item__c ();
                cusTemp.Amount__c = eachRecord.cit.Amount__c;
                cusTemp.Date__c = eachRecord.cit.Date__c;
                cusTemp.Custom_Information__c = eachRecord.cit.Custom_Information__c;
                cusTemp.Custom_Name_Type__c = eachRecord.cit.Custom_Name_Type__c;
                cusTemp.Custom_Name_Type2__c = eachRecord.cit.Custom_Name_Type2__c;

                cusTemp.Custom_object1__c = co_custom.id;
                newCustomsList.add(cusTemp);

            }
        }

        if(newCustomsList.size() > 0) {
            insert newCustomsList;
        }

        PageReference pageref = new PageReference('/' + co_custom.Id);
        pageref.setRedirect(true);
        return pageref;
    }


    public void onChangeVal(){

        if(selectedRT == 'ABC'){
            form1 = true;
            form2 = false;
        }

        else if(selectedRT == 'DEF'){
            form1 = false;
            form2 = true;
        }

        else{
            form1 = false;
            form2 = false;
        }
    } 

    public class CustomWrapper {

        public Integer index {get;set;}
        public Custom_Item__c cit {get;set;}

    }

}

Best Answer

A common pattern is:

Parent__c p = new Parent__c();
insert p;
Child__c c = new Child__c(Parent__c = p.Id);
insert c;

The explanation is that to hook up a child object you most have the parent Id available and that is not available until after the parent object has been inserted; it is set on the parent object as part of the insert operation. Child objects are related to parents via a foreign key field which in custom objects defaults to the same name as the parent object type name i.e. Parent__c in this case. Setting that field hooks the child up to the parent.

(Note that there are also reference fields - ones that end in __r - but these are not the mechanism to create the association; they are only populated when the parent and child are queried together.)

Related Topic