0

Error - Constructor not defined: [PrepareSandboxPostCopy_Batch].()

Test Class

@isTest
private class SandboxPostRefreshTestCase {

    static Testmethod void testSandboxPostCopyScript() {

        Account accVar = new Account();
        accVar.Name ='Account Test';
        INSERT accVar;

        Contact conVar = new Contact();
        conVar.LastName ='Contact Test';
        conVar.AccountId =accVar.Id;
        conVar.Email = '[email protected]';
        conVar.Other_Email__c = '[email protected]';
        INSERT conVar;

        Case casVar = new Case();
        casVar.Origin ='Email';
        casVar.Status = 'New';
        // casVar.ContactEmail = '[email protected]';
        casVar.SuppliedEmail = '[email protected]';
        INSERT casVar;

        Campaign  camVar = new Campaign();
        camVar.Name ='test';
        INSERT camVar;

        CampaignMember newMemberVar = new CampaignMember();
        newMemberVar.CampaignId = camVar.Id;
        newMemberVar.ContactId = conVar.Id;
        // newMember.Email = '[email protected]';
        INSERT newMemberVar;

        Lead leadVar = new Lead();
        leadVar.LastName = 'testsds';
        leadVar.Status = 'New';
        leadVar.Company = 'test';
        leadVar.Email = '[email protected]';
        INSERT leadVar;

        Opportunity oppVar = new Opportunity();
        oppVar.Name = 'testsds';
        oppVar.AccountId = accVar.Id;
        oppVar.CloseDate = date.today();
        oppVar.StageName = 'Proposal';
        INSERT oppVar;

        Quote quoteVar = new Quote();
        quoteVar.Name = 'testsds';
        // quoteVar.Account = accVar.Id;
        quoteVar.OpportunityId = oppVar.Id;



        Test.startTest();  

        PrepareSandboxPostCopy_Batch obj = new PrepareSandboxPostCopy_Batch();
        PrepareSandboxPostCopy_Batch.executeBatch();     
      //  system.assertEquals(true, PrepareSandboxPostCopy_Batch.isSandbox());

        Test.stopTest(); 

    }
}

This is my Apex class

global class PrepareSandboxPostCopy_Batch implements Database.Batchable<sObject> {

    String query;
    String sObjectName;
    Map <String, List <String>> sObjectEmaiLFieldsMap = new Map <String, List <String>>();

    //Call this method from the class that implements the SandboxPostCopy Interface or from Developer console
    global static void executeBatch() {
        Map <String, List <String>> sObjectEmaiLFieldsMap = getsObjectEmaiLFields();

        if(!sObjectEmaiLFieldsMap.isEmpty()) {
            Database.executeBatch(new PrepareSandboxPostCopy_Batch(sObjectEmaiLFieldsMap));
        }
    }

    /** BATCHABLE INTERFACE IMPLEMENTATION STARTS **/
    global PrepareSandboxPostCopy_Batch(Map <String, List <String>> sObjectFieldsMap) {
        //Get First Key In Map
        sObjectName = new List<String> (sObjectFieldsMap.keySet()).get(0);

        sObjectEmaiLFieldsMap = sObjectFieldsMap;
        query = getSOQLString(sObjectName, sObjectEmaiLFieldsMap.get(sObjectName));
    }

    global Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator(query);
    }    

    global void execute(Database.BatchableContext BC, List<sObject> scope) {

        for(sObject thisRecord : scope) {
            for(String thisField : sObjectEmaiLFieldsMap.get(sObjectName)) {
                String email = (String) thisRecord.get(thisField);
                if(String.isEmpty(email) || email.contains('.invalid') || email.contains('.noemail')) continue; //If empty or if contains .invalid then do not update
                thisRecord.put(thisField, email + '.invalid'); //Append invalid to the email
            }
        }
        Database.update(scope, false); //allow partial success
    }

    global void finish(Database.BatchableContext BC) {
        //Remove the sObject (First Key) once the records for the sObject processed successfully
        sObjectEmaiLFieldsMap.remove(sObjectName);
        executeBatch(sObjectEmaiLFieldsMap);
    }
    /** BATCHABLE INTERFACE IMPLEMENTATION ENDS **/

    public static Boolean isSandbox() {
        return [SELECT IsSandbox FROM Organization WHERE Id =: UserInfo.getOrganizationId()].IsSandbox;
    }

    private static void executeBatch(Map <String, List <String>> sObjectFieldsMap) {
        if(!sObjectFieldsMap.isEmpty()) {
            Database.executeBatch(new PrepareSandboxPostCopy_Batch(sObjectFieldsMap));
        }
    }

    private static String getSOQLString(String sObjectName, List<String> sObjectFields) {

        String soqlQuery = 'SELECT {!sObjectFields} FROM {!objectTypeName} WHERE {!conditionals}';

        List<String> conditionals = new List <String>();
        for (String thisField: sObjectFields) { 
            conditionals.add(thisField + ' != NULL');
        }

        soqlQuery = soqlQuery.replace('{!sObjectFields}', String.join(sObjectFields, ' ,'));
        soqlQuery = soqlQuery.replace('{!objectTypeName}', sObjectName);
        soqlQuery = soqlQuery.replace('{!conditionals}', String.join(conditionals, ' OR '));

        if(!isSandbox()) soqlQuery = soqlQuery + ' LIMIT 0'; //For Non Sandbox (Production) Instance Do Not Update Records

        return soqlQuery;
    }

    //Get all Queryable Objects and it's email fields
    private static Map <String, List <String>> getsObjectEmaiLFields() {

        Map <String, List <String>> sObjectEmailFieldMap = new Map <String, List <String>>();

        //Only pass the selected object, dynamically getting all objects may exceed APEX CPU Limit
        List<SObjectType> sObjectsToUpdate = new List<SObjectType>{ Account.SObjectType, 
                                                                    Contact.SObjectType, 
                                                                    Case.SObjectType, 
                                                                    CampaignMember.SObjectType, 
                                                                    Lead.SObjectType, 
                                                                    Opportunity.SObjectType, 
                                                                    Quote.SObjectType };

        for(SObjectType sObjectType : sObjectsToUpdate) {

            //Describe sObject
            DescribeSObjectResult sObjectDescribe = sObjectType.getDescribe();

            String objectTypeName = sObjectDescribe.getName();

            //Skip objects we cannot query or update
            if(!sObjectDescribe.isQueryable() || !sObjectDescribe.isUpdateable()) continue;

            for(SObjectField sObjectField: sObjectDescribe.fields.getMap().values()) {

                DescribeFieldResult thisField = sObjectField.getDescribe();

                //Skip all non email fields
                if(thisField.getType() != Schema.DisplayType.EMAIL || !thisField.isFilterable() || !thisField.isUpdateable()) continue;

                if(sObjectEmailFieldMap.containsKey(objectTypeName)) {
                    sObjectEmailFieldMap.get(objectTypeName).add(thisField.getName());
                }
                else {
                    sObjectEmailFieldMap.put(objectTypeName, new List <String> {thisField.getName()});
                }
            }
        }
        return sObjectEmailFieldMap;
    }
}
1

2 Answers 2

1

The reason your test class is not saving is because you have explicitly defined a constructor in your main class as PrepareSandboxPostCopy_Batch(sObjectFieldsMap). Therefore you don't have access to the default constructor PrepareSandboxPostCopy_Batch() i.e. constructor without any params.

You will have to instantiate the class using this constructor in your test class PrepareSandboxPostCopy_Batch(sObjectFieldsMap).

1
  • Hello sir,Can you help me one more time please Using this code my Start method is calling but the second execution method in not calling can you help me Commented Jan 11, 2019 at 5:24
1

Your batch constructor override to accept parameter of type Map<String, List<String>>. So you need to pass sample input to that parameter. Update your testmethod as below.

Test.startTest();

Map<String, List<String>> sObjectFieldsMap = new Map<String, List<String>>();
sObjectFieldsMap.put('Account', new List<String>{'Name', 'BillingCity'}); //Add valid sObject and fields for code coverage 
sObjectFieldsMap.put('Contact', new List<String>{'Name', 'Email', 'Other_Email__c'}); 
sObjectFieldsMap.put('Lead', new List<String>{'LastName', 'Email'}); 
PrepareSandboxPostCopy_Batch obj = new PrepareSandboxPostCopy_Batch(sObjectFieldsMap);
PrepareSandboxPostCopy_Batch.executeBatch();

Test.stopTest(); 
12
  • Hello sir Can you help me one more time please Using this code my Start method is calling but the second execution method in not calling can you help me Commented Jan 11, 2019 at 5:20
  • Map<String, List<String>> sObjectFieldsMap = new Map<String, List<String>>(); sObjectFieldsMap.put('Contact', new List<String>{'Name, Email, Other_Email__c'}); sObjectFieldsMap.put('Lead', new List<String>{'LastName, Email'}); PrepareSandboxPostCopy_Batch obj = new PrepareSandboxPostCopy_Batch(sObjectFieldsMap); Id batchId = Database.executeBatch(obj); Commented Jan 11, 2019 at 5:22
  • @LokeshMalviya Please verify if your start method returns any records. I can see it uses query variable but you did not populated query string at all.
    – Reshma
    Commented Jan 11, 2019 at 5:31
  • i didn't get you, you mean i have to also pass the query from my test class Commented Jan 11, 2019 at 6:15
  • Please put a debug to check query in start method
    – Reshma
    Commented Jan 11, 2019 at 6:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .