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
lucky0111lucky0111 

Stuck at 66% test coverage and about to cry

I'm a complete n00b at this and am eternally grateful for any assistance.

 

The goal is to automated round robin lead assignments.  I’ve installed the Round Robin Record Assignment app which is designed for Cases, but as others have said here and elsewhere, it needs some modification to make it work for Leads.  I’ve followed the instructions to create the triggers leadOwnerUpdate and leadRoundRobin based on what was built in for Cases (I would link to the page where I got the leadRoundRobin code, but I can’t seem to find it right now – it’s basically using Lead instead of Case in these new triggers).  I also created a class called TestMethodCls4 which is based on what’s included for the package for testing Cases, but it’s saying I’ve only got 66% test coverage when I try to deploy the two new triggers and class from the Sandbox to the Enterprise account.

 

Can anyone provide any assistance as to how I should update my test class to get at least 9% more coverage?  I've been up almost the entire night working on this and researching what I could find online, so this is a last resort.  Thank you in advance!

tomcollinstomcollins

Force.com shows you which lines haven't been covered by test cases.  You just need to look at the lines that don't get covered, and find a way to call the given function with parameters that will trigger that code.

Shreya...Shreya...

If you want to coverer more then 
through eclipse it's chow's which line's are not covered
most of the time due to validation rule problem secures so try to resolve it.. :D
Best of luck

 

Regards,

SHreyaaa
Fight till die 

 

 

 

jgrossmanjgrossman

I am trying to get the round robin record assignment to work with leads and have not been able to get it to work. Were you successful? I am very new to the force language and don't understand the requirements.

 

I had posted a similar question on the customer community forum but receive no real answer. Here was my previous post. Anybody can help please let me know!

 

I am looking for any help I can get with making the app exchange app Round Robin Record Assignment work with leads and not just cases. There is code posted on GitHub to create two new triggers for Leads. You can see it here.  I set up a sand box and installed the app. I then created the two apex triggers for leads. (i did this by going to leads, trigger, new) I looked at the test class that was installed and changed everywhere it said 'Case' to 'Lead' but when i go into the app and try and do a new Assignment Group the only option is still just for cases. It does not seem to pick up the ability to work for leads.

I know very little about the apex triggers and classes. I am obviously missing something simple but just can not figure it out. I have looked thru all the comment on this page.  but nothing seems to click for me.

So now I am turning to the community to see if anyone can help. Does anyone have this app working with leads? Can anyone help explain what I am missing? I need to get this done so that the reps are happy but I just don't know what to do next. Any help at all will be very much appreciated.

rgilrgil

Did you get a solution for this? i am at the same position you are and have been at it for what feels like days....

jgrossmanjgrossman

I did get this to work. And it is a nice little app I must say. For me the issue was I had to go into the object of Assignment Group. So i went to Setup: create | objects. I selected Assigment Group. From there there is a field called type. If memory serves me right all I had to do was to add the second option of Leads into the picklist and that gave me the ability to select the leads and have the code that was applied working. 

 

I have to apologize on not following up when I fixed the issue. If you try that and it does not work let me know I can try and remember if there was anthing else I did to get it to work.

 

rgilrgil

Thanks jgrossman for the quick response but my issue relates to the 66% test coverage of the appex code. I had successfully added the Leads option to the drop donw list but this does not effect the appex code test coverage. 

jgrossmanjgrossman

Hi rgil,

 

Again sorry since it has been a little while since I got this up and running I dont quite remeber all the issues as they happened. I do remeber that what I described was my last issue. Before that I did not understand creating two seperate apex triggers called leadOwnerUpadte and leadRoundRobin. 

 

The code I have in each one is as follows:

 

leadOwnerUpadte

// leadOwnerUpdate.trigger:

trigger leadOwnerUpdate on Lead (after update) {
    List<Lead> updateLeads = new List<Lead>();
    Map<Id,Lead> leads = new Map<Id,Lead>();
    
    for (Lead l : Trigger.new)
    {
        if(Trigger.isUpdate) {  
            System.debug('>>>>> Owner ID: '+l.ownerId+' Temp Owner ID: '+ l.TempOwnerId__c);
            if(l.TempOwnerId__c <> null && l.TempOwnerId__c <> '') {
                if(l.OwnerId <> l.TempOwnerId__c) {
                    leads.put(l.id,l);
                }
            }           
        }   
    }
    if (leads.isEmpty()) return;
    
    for (Lead l : [SELECT OwnerId,TempOwnerId__c FROM Lead WHERE id in :leads.keySet()]) {
        l.OwnerId = leads.get(l.Id).TempOwnerId__c;
        l.TempOwnerId__c = 'SKIP'; //flag to stop infinite loop upon update
        updateLeads.add(l);
    }
    System.debug('>>>>>Update Leads: '+updateLeads);
    
    //
    //Update last assignment for Assignment Group in batch
    //
    if (updateLeads.size() > 0) {
        try {
            update updateLeads;
        } catch (Exception e){

        }
    }
}

 leadRoundRobin

// leadsRoundRobin.trigger:

trigger leadRoundRobin on Lead (before insert, before update) {
 //
    //Check if assignment owner has changed
    //
    Map<Integer,Id> queueIds = new Map<Integer,Id>();   //Trigger index --> Queue ID
    
    Integer idx = 0;
    for (Lead l : Trigger.new)
    {
        if(Trigger.isUpdate) {  
            if(l.OwnerId <> Trigger.oldMap.get(l.id).OwnerId) {
                if (l.TempOwnerId__c == 'SKIP') {
                    Trigger.new[idx].TempOwnerId__c = '';
                } else {
                    queueIds.put(idx, l.OwnerId);
                }
            }           
        }else {
            queueIds.put(idx, l.OwnerId);
        }   
        idx++;
    }
    System.debug('>>>>>queueIds: '+queueIds);
    if (queueIds.isEmpty()) return;
    
    //
    //Find active Assignment Group for Queue
    //
    Map<Integer,Id> asgnGroupNameIds = new Map<Integer,Id>();   //Trigger index --> Assignment_Group_Name ID
    Map<Id,Assignment_Group_Queues__c> asgnGroupQueues = new Map<Id,Assignment_Group_Queues__c>(); //Queue ID --> Assignment Group Queues
    
    for(Assignment_Group_Queues__c[] agq : [SELECT Assignment_Group_Name__c, QueueId__c
                                          FROM Assignment_Group_Queues__c 
                                          WHERE QueueId__c in :queueIds.values()
                                          AND Active__c = 'True'])
    {
        for (Integer i = 0; i < agq.size() ; i++) {
            asgnGroupQueues.put(agq[i].QueueId__c, agq[i]);
        }                                           
    }
    System.debug('>>>>>asgnGroupQueues: '+asgnGroupQueues); 
    if (asgnGroupQueues.isEmpty()) return;

    for (Integer i : queueIds.keySet()) {
        Assignment_Group_Queues__c agq = asgnGroupQueues.get(queueIds.get(i));
        
        if (agq <> null) {
            asgnGroupNameIds.put(i, agq.Assignment_Group_Name__c);
        }
        //else no active assignment group queue error
    }
    System.debug('>>>>>asgnGroupNameIds: '+asgnGroupNameIds);
    if (asgnGroupNameIds.isEmpty()) return;
    
    //
    //Determine next valid user in Queue/Assignment Group for round robin
    //User with earliest last assignment date wins.
    //
    Map<Id,Assignment_Groups__c[]> asgnGroups = new Map<Id,Assignment_Groups__c[]>(); // Assignment Group Name ID --> User ID
    for(Assignment_Groups__c[] ags : [SELECT Group_Name__c, User__c, Last_Assignment__c, Millisecond__c 
                                   FROM Assignment_Groups__c 
                                   WHERE Group_Name__c in :asgnGroupNameIds.values() 
                                   AND Active__c = 'True' AND User_Active__c = 'True'
                                   ORDER BY Last_Assignment__c, Millisecond__c])
    {
        if (ags.size()>0) {
            asgnGroups.put(ags[0].Group_Name__c, ags);
        }
    }
    System.debug('>>>>>asgnGroups: '+asgnGroups);   
    if (asgnGroups.isEmpty()) return;

    Map<Id,Assignment_Groups__c> updateAssignmentGroups = new Map<Id,Assignment_Groups__c>();
    Map<Id, datetime> latestAGDateTime = new Map<Id,datetime>();
    idx = 0;    
    for (Integer i : queueIds.keySet())
    {
        Assignment_Groups__c[] ags = asgnGroups.get(asgnGroupNameIds.get(i));
        if (ags.size()>0)
        {   
            //Choose next user in line if user ID has already been used but not committed in this trigger batch 
            Assignment_Groups__c ag = ags[math.mod(idx, ags.size())];
                
            //Assign User to Lead as the new owner
            System.debug('>>>>>Owner changed for Lead ' + Trigger.new[i].Id + ' from '+Trigger.new[i].OwnerId+' to '+ ag.User__c);
            Trigger.new[i].OwnerId = ag.User__c;    
            Trigger.new[i].TempOwnerId__c = '';  // don't assign back in an endless loop

            //Set last assignment datetime
            datetime now = datetime.now();
            ag.Last_Assignment__c = now;
            ag.Millisecond__c = now.millisecondGMT();
            
            //update only latest Assignment Groups per ID
            if (latestAGDateTime.containsKey(ag.id)) {
                if(latestAGDateTime.get(ag.id) < now) {
                    updateAssignmentGroups.put(ag.id, ag);
                    latestAGDateTime.put(ag.id, now);
                }
            } else {
                updateAssignmentGroups.put(ag.id, ag);
                latestAGDateTime.put(ag.id,now);
            }
            
            idx++;
        }
    }
    //Map --> List/Array for DML update
    List<Assignment_Groups__c> updateAG = new List<Assignment_Groups__c>();
    for (Id agId : updateAssignmentGroups.keySet()) {
        updateAG.add(updateAssignmentGroups.get(agId));
    }

    System.debug('>>>>>Update Assignment Groups: '+updateAG);   
    
    //
    //Update last assignment for Assignment Group in batch
    //
    if (updateAG.size()>0) {
        try {
            update updateAG;
        } catch (Exception e){
            for (Integer i : queueIds.keySet())
            {
                Trigger.new[i].addError('ERROR: Could not update Assignment Group records ' + ' DETAIL: '+e.getMessage());  
            }
        }
    }
}

 

I remember having to create these first on my sandbox and then used the tool to move them over to production. I dont quite remember that process entirely but I think I just googled it. 

 

I am pretty sure I used cloud deploy to get it over. 

http://www.youtube.com/watch?v=FIgVhP9Guh8

You can also use Cloud Deploy, located in Setup under Develop > Deploy, to upload your trigger and tests from sandbox to production.

 

Not sure if any of that wil help but look it over give it a try and let me know. 

 

 

JDizzle53JDizzle53

Make sure that all System Administrators have Assignment Group Active checked.

 

This is the test class that worked for me to get 89% coverage

 

@isTest
private class TestMethodCls3 {

    static testMethod void myTest1() {

        // This code runs as the system user

        User u1;

        try{
          u1 = [select Id from User WHERE IsActive=True AND Profile.Name = 'System Administrator'  LIMIT 1];
        } catch (QueryException qe){

        List<User> users = [SELECT Id, Profile.PermissionsModifyAllData FROM User WHERE IsActive = true LIMIT 1000];

        for(User u : users){
            if(u.Profile.PermissionsModifyAllData = true){
              u1 = u;
              break;
        }
        }

        }

        System.debug(u1);

       //*****Create Queue 
       
       Group testGroup = new Group ();
       testGroup.Name = 'TestQueue';
       testGroup.Type = 'Queue';
       insert testGroup;
       
       QueueSObject testQueue = new QueueSObject();
       testQueue.QueueId = testGroup.id;
       testQueue.SObjectType = 'Lead';
       insert testQueue;

       // Second Queue       
       Group testGroup2 = new Group ();
       testGroup2.Name = 'TestQueue2';
       testGroup2.Type = 'Queue';
       insert testGroup2;
       
       QueueSObject testQueue2 = new QueueSObject();
       testQueue2.QueueId = testGroup2.id;
       testQueue2.SObjectType = 'Lead';
       insert testQueue2;


       test.starttest();
        
        //Run test

        //Assign Lead with out any Assignment Groups
        Lead c1 = new Lead (LastName='testLead',Company='fake',tempOwnerID__c=testGroup2.id, OwnerID=u1.id); //tempOwnerID__c=testGroup2.id,  
        insert c1;
        update c1;
        
        
        //Create Assignment Group
        Assignment_Group_Name__c ag1 = new Assignment_Group_Name__c (Name='TestAG', Type__c = 'Lead');
        insert ag1;

         
        //Add bad queue name
        Assignment_Group_Queues__c agqBad = new Assignment_Group_Queues__c(name='Bad Queue',Assignment_Group_Name__c = ag1.id );

        try {
            insert agqBad; 
        } catch (DmlException e){
             System.assert(e.getMessage().contains('CUSTOM_VALIDATION_EXCEPTION'), e.getMessage()); 
        
        } //catch

        test.stoptest();
        
    }
    
    static testMethod void myTest2() {

        // This code runs as the system user

        User u1;

        try{
          u1 = [select Id from User WHERE IsActive=True AND Profile.Name = 'System Administrator'  LIMIT 1];
        } catch (QueryException qe){

        List<User> users = [SELECT Id, Profile.PermissionsModifyAllData FROM User WHERE IsActive = true LIMIT 1000];

        for(User u : users){
            if(u.Profile.PermissionsModifyAllData = true){
              u1 = u;
              break;
        }
        }

        }

        System.debug(u1);

       //*****Create Queue 
       
       Group testGroup = new Group ();
       testGroup.Name = 'TestQueue';
       testGroup.Type = 'Queue';
       insert testGroup;
       
       QueueSObject testQueue = new QueueSObject();
       testQueue.QueueId = testGroup.id;
       testQueue.SObjectType = 'Lead';
       insert testQueue;

       // Second Queue       
       Group testGroup2 = new Group ();
       testGroup2.Name = 'TestQueue2';
       testGroup2.Type = 'Queue';
       insert testGroup2;
       
       QueueSObject testQueue2 = new QueueSObject();
       testQueue2.QueueId = testGroup2.id;
       testQueue2.SObjectType = 'Lead';
       insert testQueue2;


       test.starttest();
        
        //Run test
       
        
        //Create Assignment Group
        Assignment_Group_Name__c ag1 = new Assignment_Group_Name__c (Name='TestAG', Type__c = 'Lead');
        insert ag1;        

        //Add Good Queue to Assignment Group
        Assignment_Group_Queues__c agq1 = new Assignment_Group_Queues__c(name=testGroup.Name ,Assignment_Group_Name__c = ag1.id );
        insert agq1;
        
        
        //Add User to Assignment Groups Users
        Assignment_Groups__c agu1 = new Assignment_Groups__c (User__c = u1.id, Active__c='True', Group_Name__c = ag1.id, Last_Assignment__c = datetime.valueOf('2009-01-01 21:13:24') );
        insert agu1;

        Lead c2 = new Lead (LastName='testLead2', Company='fake2',tempOwnerID__c=testGroup2.id , OwnerID=testGroup.id); //Set owner ID to Queue
        insert c2;
        update c2;        

        test.stoptest();
        
    }

    static testMethod void myTest3() {

        // This code runs as the system user

        User u1;

        try{
          u1 = [select Id from User WHERE IsActive=True AND Profile.Name = 'System Administrator'  LIMIT 1];
        } catch (QueryException qe){

        List<User> users = [SELECT Id, Profile.PermissionsModifyAllData FROM User WHERE IsActive = true LIMIT 1000];

        for(User u : users){
            if(u.Profile.PermissionsModifyAllData = true){
              u1 = u;
              break;
        }
        }

        }

        System.debug(u1);

       //*****Create Queue 
       
       Group testGroup = new Group ();
       testGroup.Name = 'TestQueue';
       testGroup.Type = 'Queue';
       insert testGroup;
       
       QueueSObject testQueue = new QueueSObject();
       testQueue.QueueId = testGroup.id;
       testQueue.SObjectType = 'Lead';
       insert testQueue;

       test.starttest();
        
        //Run test        
        
        //Create Assignment Group
        Assignment_Group_Name__c ag1 = new Assignment_Group_Name__c (Name='TestAG', Type__c = 'Lead');
        insert ag1;        

        //Add Good Queue to Assignment Group
        Assignment_Group_Queues__c agq1 = new Assignment_Group_Queues__c(name=testGroup.Name ,Assignment_Group_Name__c = ag1.id );
        insert agq1;
        
        
        //Add User to Assignment Groups Users
        Assignment_Groups__c agu1 = new Assignment_Groups__c (User__c = u1.id, Active__c='True', Group_Name__c = ag1.id, Last_Assignment__c = datetime.valueOf('2009-01-01 21:13:24') );
        insert agu1;      
 
        Lead c3 = new Lead (LastName='testLead3', Company='test company 3',OwnerID=testGroup.id); //Set owner ID to Queue
        insert c3;
        update c3;

        test.stoptest();
        
    }

    static testMethod void myTest4() {

        // This code runs as the system user

        User u1;

        try{
          u1 = [select Id from User WHERE IsActive=True AND Profile.Name = 'System Administrator'  LIMIT 1];
        } catch (QueryException qe){

        List<User> users = [SELECT Id, Profile.PermissionsModifyAllData FROM User WHERE IsActive = true LIMIT 1000];

        for(User u : users){
            if(u.Profile.PermissionsModifyAllData = true){
              u1 = u;
              break;
        }
        }

        }

        System.debug(u1);

       //*****Create Queue 
       
       Group testGroup = new Group ();
       testGroup.Name = 'TestQueue';
       testGroup.Type = 'Queue';
       insert testGroup;
       
       QueueSObject testQueue = new QueueSObject();
       testQueue.QueueId = testGroup.id;
       testQueue.SObjectType = 'Lead';
       insert testQueue;
      

       test.starttest();
        
        //Run test

        //Create Assignment Group
        Assignment_Group_Name__c ag1 = new Assignment_Group_Name__c (Name='TestAG', Type__c = 'Lead');
        insert ag1;        

        //Add Good Queue to Assignment Group
        Assignment_Group_Queues__c agq1 = new Assignment_Group_Queues__c(name=testGroup.Name ,Assignment_Group_Name__c = ag1.id );
        insert agq1;
        
          //Test for AG-Queues already assigned to another Assignment Group
        Assignment_Group_Queues__c agq2 = new Assignment_Group_Queues__c(name=testGroup.Name,Assignment_Group_Name__c = ag1.id );
        try {
            insert agq2;
        } catch (DmlException e){
             System.assert(e.getMessage().contains('CUSTOM_VALIDATION_EXCEPTION'), e.getMessage()); 
        } //catch

        test.stoptest();
        
    }
    
    static testMethod void myTest5() {

        // This code runs as the system user
        User u1;

        try{
          u1 = [select Id from User WHERE IsActive=True AND Profile.Name = 'System Administrator'  LIMIT 1];
        } catch (QueryException qe){

        List<User> users = [SELECT Id, Profile.PermissionsModifyAllData FROM User WHERE IsActive = true LIMIT 1000];

        for(User u : users){
            if(u.Profile.PermissionsModifyAllData = true){
              u1 = u;
              break;
        }
        }
        }

        System.debug(u1);

       //*****Create Queue 
       Group testGroup = new Group ();
       testGroup.Name = 'TestQueue';
       testGroup.Type = 'Queue';
       insert testGroup;
       
       Group testGroup2 = new Group();
       testGroup2.Name = 'TestQueue2';
       testGroup2.Type = 'Queue';
       insert testGroup2;
       
       QueueSObject testQueue = new QueueSObject();
       testQueue.QueueId = testGroup.id;
       testQueue.SObjectType = 'Lead';
       insert testQueue;
      
       QueueSObject testQueue2 = new QueueSObject();
       testQueue2.QueueId = testGroup2.id;
       testQueue2.SObjectType = 'Lead';
       insert testQueue2;

       test.starttest();
       
        //Run test
        //Create Assignment Group
        Assignment_Group_Name__c ag1 = new Assignment_Group_Name__c (Name='TestAG', Type__c = 'Lead');
        insert ag1;        

        //Add Good Queue to Assignment Group
        Assignment_Group_Queues__c agq1 = new Assignment_Group_Queues__c(name=testGroup.Name ,Assignment_Group_Name__c = ag1.id );
        insert agq1;
        
        //Add Group Member
        Assignment_Groups__c agu1 = new Assignment_Groups__c (User__c = u1.id, Active__c='True', Group_Name__c = ag1.id, Last_Assignment__c = datetime.valueOf('2009-01-01 21:13:24') );
        insert agu1;
        
        //Add Lead
        Lead l = new Lead(LastName = 'Tester', Company = 'LeadMD', Description = 'Testy', OwnerID = testGroup.id);
        insert l;
        system.assertEquals(l.OwnerID, testGroup.id);
        l.OwnerID = testGroup2.id;
        l.TempOwnerId__c = 'SKIP';
        update l;
        system.assertEquals(l.OwnerID, testGroup2.id);
        l.OwnerID = testGroup.id;
        l.TempOwnerId__c = '';
        update l;
        system.assertEquals(l.OwnerID, testGroup.id);
        
        //Test for AG-Queues already assigned to another Assignment Group
        Assignment_Group_Queues__c agq2 = new Assignment_Group_Queues__c(name=testGroup.Name,Assignment_Group_Name__c = ag1.id );
        try {
            insert agq2;
        } catch (DmlException e){
            System.assert(e.getMessage().contains('CUSTOM_VALIDATION_EXCEPTION'), e.getMessage()); 
        }
        
        Assignment_Group_Queues__c agqBad = new Assignment_Group_Queues__c(name='Bad Queue',Assignment_Group_Name__c = ag1.id);
        try {
            insert agqBad;
        } catch (DmlException e){
             System.assert(e.getMessage().contains('CUSTOM_VALIDATION_EXCEPTION'), e.getMessage());
        }
        
        ag1.Name = 'TestAG22';
        update ag1;
        
        system.assertEquals(ag1.Name, 'TestAG22');
        
        Assignment_Group_Name__c ag2 = new Assignment_Group_Name__c(Name='TestAG22', Type__c = 'Lead');
        insert ag2;
        Assignment_Group_Queues__c agq3 = new Assignment_Group_Queues__c(name=testGroup2.Name, Assignment_Group_Name__c = ag2.id);
        insert agq3;

        
        system.assertEquals(agq3.Name, 'TestQueue2');
        
        if(l.OwnerID == 'a06K0000001rYWl')
        {
            l.OwnerID = '';
        }else{
            l.OwnerID = testQueue2.id;
            System.assertEquals(l.OwnerID, testQueue2.id);
        }
                
        test.stoptest();
    }
    
}

 

ss1ss1

So, SFDC won't let me create this new class in production, so I created it in sandbox, and promoted it via a change set.  But it won't deploy, as it doesn't have sufficient test coverage (?!)

 

test coverage of the test class is only 63%

 

ss1ss1

I finally stumbled all the way through this, to get it working for leads... In a nutshell :

 

Get the GitHub code, deploy in sandbox. Ultimately, you can use change sets to promote this to production.

 

You need an Apex test class to validate the github code. Deploy this in Sandbox and validate the code. When you deploy this test class it too must validate.

 

Once everything is validated and apparently working in sandbox, create a single change set with the 3 items - 1 class, 2 triggers, and upload it to production. It should validate and deploy in production.

 

Now, you can start the configuration process per the instructions - just think "leads" instead of cases.

 

As someone mentioned above, you do need to edit the Type field in custom objects, to add a picklist value of Leads.

 

Consider if want the default lead owner to be the round robin queue.

 

Consider a workflow rule to assign un-assigned leads to the round robin queue.

sethi0007771.395862520819969E12sethi0007771.395862520819969E12
Let me share the One of easiest trick with you and I believe i am the only one who knows,  see if you stuck with any test coverage after 50% done, and you have to achieve 75% , you just need to reduce the Code length of your class or trigger , You need to placed uncovered red lines with corresponding covered blue lines.  

Please follow this trick , only if you are about to cry or in very urgency, It is Salesforce limitation