function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Tanmay SahaiTanmay Sahai 

Error when running the Test Class

Hi All,
I have created a Test Class to deploy my Apex Class. My Apex class is invocble and is working fine in Sandbox. However, when I try to execute my Test Class, I get the below error:
Apex Test Result Detail 
Time Started7/3/2018 11:44 PM
ClassAutoConvertLeadsTest
Method NameAutoConvertLeads
Pass/FailFail
Error MessageSystem.DmlException: ConvertLead failed. First exception on row 0; first error: INVALID_CROSS_REFERENCE_KEY, valid leadId is required: []
Stack TraceClass.AutoConvertLeads.LeadAssign: line 17, column 1
Class.AutoConvertLeadsTest.AutoConvertLeads: line 26, column 1

Below is the code for my Apex Class ( This class is then used in a PB to convert leads) :
Public class AutoConvertLeads
{
    @InvocableMethod
    public static void LeadAssign(List<Id> LeadIds)
    {
        LeadStatus CLeadStatus= [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true];
        List<Database.LeadConvert> MassLeadconvert = new List<Database.LeadConvert>();
        for(id currentlead: LeadIds){
                Database.LeadConvert Leadconvert = new Database.LeadConvert();
                Leadconvert.setLeadId(currentlead);                
                Leadconvert.setConvertedStatus(CLeadStatus.MasterLabel);
                Leadconvert.setDoNotCreateOpportunity(TRUE); //Remove this line if you want to create an opportunity from Lead Conversion
                MassLeadconvert.add(Leadconvert);
        }
        
        if (!MassLeadconvert.isEmpty()) {
            List<Database.LeadConvertResult> lcr = Database.convertLead(MassLeadconvert);
        }
    }
}

And this is the code for my Test Class:
@isTest (seeAllData = true )
private class AutoConvertLeadsTest {

    static testMethod void AutoConvertLeads() {
            List<id> LeadIds=new List<id>();
            for(LeadStatus a : [select id from LeadStatus]){
                LeadIds.add(a.id);
            }
        AutoConvertLeads Obj = new AutoConvertLeads();
    AutoConvertLeads.LeadAssign(LeadIds);
            
        }

}

Not sure where am I going wrong or am I missing any steps?
Steven NsubugaSteven Nsubuga
you needed to create lead records for use in testing
@isTest 
private class AutoConvertLeadsTest {

    static testMethod void AutoConvertLeads() {
            List<id> LeadIds=new List<id>();
            List<Lead> Leads=new List<Lead>();
            for(integer a = 1; a < 4; a++){
                Lead la = new Lead (LastName = 'Lead '+a, Company='Fries');
                Leads.add(la);
            }
            insert Leads;
            
            for(Lead Leada : Leads) {
               LeadIds.add(Leada.id);
            }
            
        AutoConvertLeads Obj = new AutoConvertLeads();
        AutoConvertLeads.LeadAssign(LeadIds);
            
    }

}

 
Shruti SShruti S

In your test class, you are actually querying the LeadStatus and passing the list of LeadStatus Ids instead of passing the list of Lead Ids.

Please try the below code :

@isTest
private class AutoConvertLeadsTest {
    static testMethod void AutoConvertLeads() {
        Lead newLead        = new Lead();
        newLead.LastName    = 'Test Lead';
        newLead.Company     = 'Test Company';
        newLead.Status      = 'Open - Not contacted';
        newLead.LeadSource  = 'Web';
        INSERT newLead;
        
        List<Id> leadIds = new List<Id>();
        for( Lead ld : [ SELECT Id FROM Lead ] ) {
            leadIds.add( ld.Id );
        }
        
        AutoConvertLeads.LeadAssign( leadIds );
    }
}
Tanmay SahaiTanmay Sahai
Hello Steven & Shruti,

Thank you guys for your prompt response. I was able to fix the error and was also successfully able to deploy the test class. Howvr,my Apex Class is showing 0% code coverage. I am sure it is bulkified but still not able to deploy it. Can you guys please help me with the code coverage of atleast 75%.
Await your response. Thanks!
Shruti SShruti S
You can try out my code. It should give you 100% code coverage.
Steven NsubugaSteven Nsubuga
The test class I shared resulted in 100% code coverage of the Apex Class. Run the test again after deployment. 
Tanmay SahaiTanmay Sahai
Also, may be I am making some errors during the deployment process using ChangeSets.
These are steps that I follow:
In Sandbox:
Open Outbound Change Set>>Add both the Test and the Apex Class>>Upload
In Production:
Open Inbound Change Set>>Validate>>Choose Specific(option 4) and put the Name of both classes.

My componets are validated successfully but I get the Fatal Apex Error stating : "Your code is coverage is 0%. Your code should have atleast 75% code coverage to complete deployment." Class: AutoConvertLeads

Am I doing something wrong?? Await your responses.

Thanks!
Steven NsubugaSteven Nsubuga
First run the test in the sandbox to see the code coverage
Steven NsubugaSteven Nsubuga
After running the test class I created, I got 100% code coverage. Perhaps you used a different test class or you did not deploy both the class and the test class in the same deployment.
User-added image
Tanmay SahaiTanmay Sahai
Hi Steven,

I have run the Apex Test Execution of the test class in Sandbox and it gives me 100% code coverage. I assume that I am doing something wrong while deploying my code. Any idea what is the wrong step??

Thanks again!
Steven NsubugaSteven Nsubuga
Make sure that both classes have been included in the changeset uploaded to production. Then when the changeset is available on production, validate and deploy using the default options.
Shruti SShruti S
Could you give me a Screenshot of your Changeset?
Steven NsubugaSteven Nsubuga
Run all tests in Production to ensure that the existing tests there all pass even before you deploy this change set. Make sure the change set only has the 2 classes.
Tanmay SahaiTanmay Sahai
Hi,
Here is the screenshot of the Inbound Change Set in Prod:
InBound Change Set
Tanmay SahaiTanmay Sahai
And this is how I am validating:

User-added image
Tanmay SahaiTanmay Sahai
And this is the Validation error:

User-added image
Shruti SShruti S
Could you try with 'Default' option in Validate Change Set window?
Tanmay SahaiTanmay Sahai
Hi Shruti,

I have tried the default option as well. The system checks for all the managed package classes as well other classes already deployed and it fails as the total code coverage turns out to be 73%.

Any other option that you may think of??

Because the code coverage for both these classes is more than 75% that is what my assumption is.

Thanks!
Tanmay SahaiTanmay Sahai
And here is the screenshot which shows that my code coverage is 100%:

User-added image
Shruti SShruti S
No there is no way out. The code coverage of the entire org should be 75% and above to do any deployments.
Tanmay SahaiTanmay Sahai
Then why doesn't the Run Specified Test fail when my code coverage is already 100% as per the screen shot above??

 
Shruti SShruti S
Sorry! As far as I know there is no way to get these into the Production without improving the code coverage there.
Steven NsubugaSteven Nsubuga
Verify that aIl existing tests in production pass. Failure of some tests causes the overall code coverage to decrease.
Identify the classes in production with low code coverage and write additional tests for them so as to increase their code coverage and thus the overall code coverage of the instance.
Tanmay SahaiTanmay Sahai
Thank you both for your valuable responses. I have been able to deploy the classes successfully and the functionality is working.
 
Tanmay SahaiTanmay Sahai
Hi Steven/Shruti,

I have reworked my Apex Class as I wanted to check for the duplicate Accounts. My code is working fine but I am having 2 issues:
1. The Company Custom Name is accepting ID instead of Name ( its a custom text field)
2. Secondly, irrespective of the Company I put in the Lead Company field, the converted contact is always attaching to the same account upon conversion.

Here is what our requirement is:

" Our leads flow into Salesforce from Admin Panel/HubSpot. Custom Company Name is a common Lead field for both HubSpot and Salesforce. When the Lead is created by flowing into Salesforce, the standard Company field of Lead is blank or [not provided].

We also have a check box on the Lead named: Created in Panel.


What we want is to convert only those leads which have this Created in Admin Panel checkbox true. Also, on conversion, the value in the Custom Company Name should overwrite the Company of the Lead thereby replacing it as Account Name on the Converted Contact.

Then, if the Account already exists, it should only create a contact and attach to the existing Account.
"

Below is my updated code:
Public class AutoConvertLeads
{
    @InvocableMethod //Used to invoke this Class in Process Builder
    public static void LeadAssign(List<Id> LeadIds)
    {
     map< id,id> mapAccount = new map<id,id>();
     {
       for(Account a : [SELECT id,Company_Name_Custom__c from Account])
        {
         mapAccount.put(a.Company_Name_Custom__c, a.id);
        }

        LeadStatus CLeadStatus= [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted = true LIMIT 1];
        List<Database.LeadConvert> MassLeadconvert = new List<Database.LeadConvert>();
        for(Lead currentlead: [SELECT Id,Company_Name_Custom__c from Lead where Id in:LeadIds ])
     {
         if( !mapAccount.isEmpty() && mapAccount.ContainsKey(currentlead.Company_Name_Custom__c) )
         {
            Database.LeadConvert Leadconvert = new Database.LeadConvert();
                Leadconvert.setLeadId(currentlead.Id);                
                Leadconvert.setConvertedStatus(CLeadStatus.MasterLabel);
                Leadconvert.setDoNotCreateOpportunity(TRUE);
                Leadconvert.setAccountId(mapAccount.get(currentlead.Company_Name_Custom__c));
                MassLeadconvert.add(Leadconvert);
             
         }
         else
         {
            Database.LeadConvert Leadconvert = new Database.LeadConvert();
                Leadconvert.setLeadId(currentlead.Id);                
                Leadconvert.setConvertedStatus(CLeadStatus.MasterLabel);
                Leadconvert.setDoNotCreateOpportunity(TRUE);
                MassLeadconvert.add(Leadconvert);
         }
      }

        
        if (!MassLeadconvert.isEmpty())
        {
            List<Database.LeadConvertResult> lcr = Database.convertLead(MassLeadconvert);
        }
    }   }    
}

I was hoping if either of you could help me tweaking my code a bit to meet the requirement. Would appreciate your help.

Await your responses.
Thanks!
Steven NsubugaSteven Nsubuga
Hi Tanmay, it is a best practice to always start a new question rather than add a new question to a previously solved question.
Not only is it discouraging to the one who solved the earlier question but it also reduces the chances that other people will chip in to help solve the new question.