+ Start a Discussion
Rishabh Patel 1Rishabh Patel 1 

Test Class for Dynamic SOQL

I am doing a SOQL query and then updating records. The trick here is . I am grabbing my query from two custom fields which are in the Custom Settings . My code works fine records are getting queried and updated. I am having big trouble in making test class for this . Help is appriciated . Here is my Apex Class -

public with sharing class textInputsConsecond implements Schedulable   { 
 public list<Lead>  quo{get;set;}


 public void execute(SchedulableContext ctx){ 
   quo= Database.query(Lead__c.getInstance().Database_Query__c + 
   Lead__c.getInstance().Database_Query2__c);
   for(Lead ldt :quo){
   //Update those leads with new owner ID
   ldt.OwnerId = '00G3B000001hp6VUAQ';

    }

   update quo;
 }
 }


Here is the screenshot of my Query in the Field in custom settings -

User-added image

So my query is basically Database Query field + Database Query2 Field

The only reason to use two fields is salesforce is not allowing text box more that 255 characters  

Best Answer chosen by Rishabh Patel 1
Raj VakatiRaj Vakati
First Step 

Remove the hardcoded Id from the Code and update the code as below 
 
public with sharing class textInputsConsecond implements Schedulable   { 
 public list<Lead>  quo{get;set;}


 public void execute(SchedulableContext ctx){ 
User u = [Select Id from User Where Email ='testasdjkasjhdkjas@gmail.com' limit 1 ]; 
   quo= Database.query(Lead__c.getInstance().Database_Query__c + 
   Lead__c.getInstance().Database_Query2__c);
   for(Lead ldt :quo){
   //Update those leads with new owner ID
   ldt.OwnerId = u.Id;

    }

   update quo;
 }
 }


And use the test class like this
 
@isTest
private class textInputsConsecondTest {
    @testSetup
   static void setup()
   {
   User u = [Select Id from User Where Email ='testasdjkasjhdkjas@gmail.com' limit 1 ];
   
       List<Lead> lstOfLead = new List<Lead>();
       for(Integer i = 1; i<= 200; i++)
       {
           Lead ld = new Lead(Company = 'Comp' +i,LastName = 'LN' + i, Status = 'Working');
		   ld.OwnerId = u.Id ;
           lstofLead.add(ld);  
       }
       Insert lstOfLead;
   }
    static testmethod void testDailyLeadProcessorScheduledJob() {
        
           String sch = '0 5 12 * * ?';
           Test.startTest(); 
           String jobId = System.schedule('ScheduleApexText', sch, new textInputsConsecond());         
    }
}

 

All Answers

Raj VakatiRaj Vakati
First Step 

Remove the hardcoded Id from the Code and update the code as below 
 
public with sharing class textInputsConsecond implements Schedulable   { 
 public list<Lead>  quo{get;set;}


 public void execute(SchedulableContext ctx){ 
User u = [Select Id from User Where Email ='testasdjkasjhdkjas@gmail.com' limit 1 ]; 
   quo= Database.query(Lead__c.getInstance().Database_Query__c + 
   Lead__c.getInstance().Database_Query2__c);
   for(Lead ldt :quo){
   //Update those leads with new owner ID
   ldt.OwnerId = u.Id;

    }

   update quo;
 }
 }


And use the test class like this
 
@isTest
private class textInputsConsecondTest {
    @testSetup
   static void setup()
   {
   User u = [Select Id from User Where Email ='testasdjkasjhdkjas@gmail.com' limit 1 ];
   
       List<Lead> lstOfLead = new List<Lead>();
       for(Integer i = 1; i<= 200; i++)
       {
           Lead ld = new Lead(Company = 'Comp' +i,LastName = 'LN' + i, Status = 'Working');
		   ld.OwnerId = u.Id ;
           lstofLead.add(ld);  
       }
       Insert lstOfLead;
   }
    static testmethod void testDailyLeadProcessorScheduledJob() {
        
           String sch = '0 5 12 * * ?';
           Test.startTest(); 
           String jobId = System.schedule('ScheduleApexText', sch, new textInputsConsecond());         
    }
}

 
This was selected as the best answer
Andrew GAndrew G
@Raj

Yes, hardcoded Ids are bad, but if we look at the OP post, the query is for Groups '00Gxxxxxx' therefore
String oldGroupName ='oldGroupOwnerName';
List<Group> oldGpList = new List<Group>();
oldGpList = [select id,name from group where name=:oldGroupName ];
//set other lead details and then owner id
Id.OwnerId = oldGpList(0).Id;

The OP code is doing a query of a certain group owner and converting to a new group, so we need the new group Owner
static testmethod void testDailyLeadProcessorScheduledJob() {
  String newGroupName ='newGroupOwnerName';
  List<Group> newGpList = new List<Group>();
  newGpList = [select id,name from group where name=:newGroupName ];
//invoke method

Asserts - without them, test code is rubbish. How do you know the code actually worked and how do you know it won't be broken when more code / other processes are updated.?
List<Leads> verifyLeads = [SELECT Id,Name,OwnerId FROM Lead WHERE LastName = 'LN'];  
System.assertEquals(verifyLeads(0).OwnerId, newGpList(0).Id);

@Rishabh

Hope the additional notes above help.

Regards
Andrew

 
Raj VakatiRaj Vakati
Yes, Andrew .. My bad it must be a group id and not used Id .. nice catch :) 
Rishabh Patel 1Rishabh Patel 1

Hello Raj and Andrew, Really appriciate you guys answering the question . So I used Rajs code and queried the Group as andrew said. The code is working fine 

Raj , When I rum the test class. I am getting this error. If you can tell what Exatly am I missing 

Time Started2/19/2019 10:40 AM
ClasstextInputsConsecondTest
Method NametestDailyLeadProcessorScheduledJob
Pass/FailFail
Error MessageSystem.QueryException: unexpected token: nullnull
Stack TraceClass.textInputsConsecond.execute: line 7, column 1

Andrew GAndrew G
Hi Rishabh
Can you post the code and test class you eventually built?  I am assuming you blended the two lots of code; so it would be easier to understand the error if we see the code.

Regards
Andrew
Rishabh Patel 1Rishabh Patel 1

Hey Andrew, Thanks for the reply  . Sorry I forgot to add the test class. 

Here you go 

@isTest
private class textInputsConsecondTest {
    @testSetup
   static void setup()
   {
   Group u = [SELECT
                Id,Name
            FROM Group
            WHERE Name = 'Unassigned Lead Retention'
            limit 1 ];
   
       List<Lead> lstOfLead = new List<Lead>();
       for(Integer i = 1; i<= 50; i++)
       {
           Lead ld = new Lead(Company = 'Comp' +i,LastName = 'LN' + i, Status = 'Working');
           ld.OwnerId = u.Id ;
           lstofLead.add(ld);  
           Task t = new Task(WhoId =ld.Id , Subject  = 'Test', ActivityDate = Date.Today());
            insert t ; 
       }
       Insert lstOfLead;
   }
    static testmethod void testDailyLeadProcessorScheduledJob() {
        
           String sch = '0 5 12 * * ?';
           Test.startTest(); 
           String jobId = System.schedule('ScheduleApexText', sch, new textInputsConsecond());         
    }
}

I am adding task to the leads too . Cause in my main query . I am getting the leads with last activity date within 7 days 
Andrew GAndrew G
Ok, the error message would indicate an issue in how you are building your query in the code, not the test code.
Based on line 7 and the message: Error MessageSystem.QueryException: unexpected token: nullnull

I would stick some debugs around the creation of the query; perhaps
String string1 = Lead__c.getInstance().Database_Query__c;
System.debug('DEBUG String one :' + string1;

String string2 = Lead__c.getInstance().Database_Query2__c;
System.debug('DEBUG String two :' + string2;

quo= Database.query(String1 + String2);
HTH
Andrew
Rishabh Patel 1Rishabh Patel 1

Hey Andrew, Thanks a lot for the reply. I finally understood what the problem is. Apex is not able to grab the Data from Custom Settings and shows Null . When I moved everything to Custom Metadata. That worked . 

Thanks again for you help on this. Really appriciate it