1

The trigger will fire on before update DML statement on Lead object. When the Role of an old Owner (i.e. old record owner) contains string 'LG' or 'Lead Gen' and the new Owner’s Role (Role of new owner) contains string 'Sales' the Qualified_By__c field will be populated with the old Owner Id.

trigger LeadOwnership on Lead (before update) 
{

    list<id> lstOwners = new list<id>();
    //trigger.old - list of the old version of Lead records
    //trigger.new - list of the new version of Lead records
    for (Integer i = 0; i < trigger.new.size(); i++)
    {
        lstOwners.add(trigger.new[i].ownerId); 
        lstOwners.add(trigger.old[i].ownerId);
    }
    map<id, User> mapUsers = new map<id, User>([Select u.UserRole.Name, u.Commission_Role__c, u.UserRoleId, u.Id From User u where id in :lstOwners]);

    for (Integer i = 0; i < trigger.new.size(); i++)
    {
        if(trigger.new[i].ownerId == trigger.old[i].ownerId)
        {
            User newUser = mapUsers.get(trigger.new[i].ownerId);
            User oldUser = mapUsers.get(trigger.old[i].ownerId);
            if((oldUser.UserRole.Name.contains('LG') || oldUser.UserRole.Name.contains('Lead Gen')) && newUser.UserRole.Name.contains('Sales'))
            {
                trigger.new[i].Qualified_By__c = oldUser.id;
            }
        }
    }
}

When I make test, the code is cover for 92%.

test what I use

@isTest
private class LeadOwnership_Test 
{
    static testMethod void myUnitTest() 
    {
        list <UserRole> LstRolesLG;

        Profile Prof = [Select p.Id From Profile p where Name like 'Standard User' limit 1][0];
        UserRole CEO = [Select u.ParentRoleId, u.Name, u.Id From UserRole u where ParentRoleId = '' limit 1][0];

        //Test Roles
        UserRole LGRole = new UserRole(Name='UserAD_Test_LG', ParentRoleId=CEO.id);
        UserRole LeadGenGRole = new UserRole(Name='UserAD_Test_Lead Gen', ParentRoleId=CEO.id);
        UserRole SalesRole = new UserRole(Name='UserAD_Test_Sales', ParentRoleId=CEO.id); 
        LstRolesLG = new UserRole[] {LGRole, LeadGenGRole};
        insert LstRolesLG;
        insert SalesRole;



        //Users
        List<User> lstUsers = new List<User>();
        integer counter = 1;
        for (UserRole objRoleLG : LstRolesLG)
        {
            User UserLG = new User();
            UserLG.LastName = 'LastName_Test_UserLG'+string.valueof(counter);
            UserLG.Alias = 'UserLG'+string.valueof(counter);
            UserLG.Email = 'Test_UserLG@example.com';
            UserLG.Username = 'Test_UserLG'+string.valueof(counter)+'@example.com';
            UserLG.CommunityNickname  = 'UserLG'+string.valueof(counter);
            UserLG.UserRoleId = objRoleLG.id;
            UserLG.IsActive = true;
            UserLG.TimeZoneSidKey = 'America/New_York';
            UserLG.LocaleSidKey = 'en_US';
            UserLG.EmailEncodingKey = 'ISO-8859-1';
            UserLG.ProfileId = Prof.Id;
            UserLG.LanguageLocaleKey = 'en_US';
            UserLG.Commission_Role__c = 'UserAD_Test_LG';
            lstUsers.add(UserLG);
            counter++;
        }
        insert lstUsers;

        User UserSales = new User();
        UserSales.LastName = 'LastName_Test_UserSales';
        UserSales.Alias = 'Sales';
        UserSales.Email = 'Test_UserSales@example.com';
        UserSales.Username = 'Test_UserSales@example.com';
        UserSales.CommunityNickname  = 'Sales';
        UserSales.UserRoleId = SalesRole.id;
        UserSales.IsActive = true;
        UserSales.TimeZoneSidKey = 'America/New_York';
        UserSales.LocaleSidKey = 'en_US';
        UserSales.EmailEncodingKey = 'ISO-8859-1';
        UserSales.ProfileId = Prof.Id;
        UserSales.LanguageLocaleKey = 'en_US';
        UserSales.Commission_Role__c = 'Lead Generator';
        lstUsers.add(UserSales);
        insert UserSales;

        User UserCEO = new User();
        UserCEO.LastName = 'LastName_Test_UserCEO';
        UserCEO.Alias = 'CEO';
        UserCEO.Email = 'Test_UserCEO@example.com';
        UserCEO.Username = 'Test_UserCEO@example.com';
        UserCEO.CommunityNickname  = 'CEO';
        UserCEO.UserRoleId = CEO.id;
        UserCEO.IsActive = true;
        UserCEO.TimeZoneSidKey = 'America/New_York';
        UserCEO.LocaleSidKey = 'en_US';
        UserCEO.EmailEncodingKey = 'ISO-8859-1';
        UserCEO.ProfileId = Prof.Id;
        UserCEO.LanguageLocaleKey = 'en_US';
        UserCEO.Commission_Role__c = 'UserAD_Test_Sales';
        lstUsers.add(UserCEO);
        insert UserCEO;

        list<User> lstUsersLGLeadGen = [Select u.UserRole.Name, u.UserRoleId, u.Id From User u where LastName like 'LastName_Test_UserLG%'];

        list<Lead> lstLeads = new list<Lead>();
        counter = 1;
        for (User objUserLGLeadGen : lstUsersLGLeadGen)
        {
            Lead objLead = new Lead(LastName='Test_Lead_LGLeadGen'+string.valueof(counter), Status='Working', Company='TestAcc0', CurrencyIsoCode='USD', OwnerId = objUserLGLeadGen.id);
            lstLeads.add(objLead);
            counter++;
        }

        for (User objUserLGLeadGen : lstUsersLGLeadGen)
        {
            Lead objLead = new Lead(LastName='Test_Lead_LGLeadGen_Neg'+string.valueof(counter), Status='Working', Company='TestAcc0', CurrencyIsoCode='USD', OwnerId = objUserLGLeadGen.id);
            lstLeads.add(objLead);
            counter++;
        }

        Lead objLeadCeo = new Lead(LastName='Test_Lead_CEO', Status='Working', Company='TestAcc0', CurrencyIsoCode='USD', OwnerId = UserCEO.id);
        lstLeads.add(objLeadCeo);
        counter++;

        System.runAs(lstUsersLGLeadGen[0]) {insert lstLeads;}

        lstLeads = [Select l.OwnerId, l.LastName, l.Id From Lead l where LastName like 'Test_Lead_LGLeadGen%'];
        list<Lead> lstLeadsNeg = [Select l.OwnerId, l.LastName, l.Id From Lead l where LastName like 'Test_Lead_LGLeadGen_Neg%'];
        list<Lead> lstLeadsNegCEO = [Select l.OwnerId, l.LastName, l.Id From Lead l where LastName like 'Test_Lead_CEO'];


        Test.startTest();

        //trigger will change owners
        for (Lead objLead : lstLeads)
        {
            objLead.OwnerId = UserSales.id;
        }
        System.runAs(UserSales) {update lstLeads;}

        //trigger won't change owners
        for (Lead objLead : lstLeadsNeg)
        {
            objLead.OwnerId = UserCEO.id;
        }
        System.runAs(UserCEO) {update lstLeads;}

        //trigger won't change owners
        for (Lead objLead : lstLeadsNegCEO)
        {
            objLead.OwnerId = UserSales.id;
        }
        System.runAs(UserSales) {update lstLeads;}

        Test.stopTest();


        //checking results
        //positive check
        list<Lead> lstLead = new list<Lead> ([Select l.OwnerId, l.LastName, l.Id, l.Qualified_By__c From Lead l where LastName='Test_Lead_LGLeadGen%']);
        for (Lead objlead :lstLead)
        {
            system.assertEquals(SalesRole.id, objlead.OwnerId);
            system.assertEquals(SalesRole.id, objlead.Qualified_By__c);
        }

        //1st negative check
        lstLead = new list<Lead> ([Select l.OwnerId, l.LastName, l.Id, l.Qualified_By__c From Lead l where LastName='Test_Lead_LGLeadGen_Neg%']);
        for (Lead objlead :lstLead)
        {
            system.assertEquals(UserCEO.id, objlead.OwnerId);
            system.assertNotEquals(SalesRole.id, objlead.Qualified_By__c);
        }

        //2nd negative check
        lstLead = new list<Lead> ([Select l.OwnerId, l.LastName, l.Id, l.Qualified_By__c From Lead l where LastName='Test_Lead_CEO%']);
        for (Lead objlead :lstLead)
        {
            system.assertEquals(UserSales.id, objlead.OwnerId);
            system.assertNotEquals(null, objlead.Qualified_By__c);
        }
    }
}

I can't see what is incorectly in the code for get 100% of cover. Can anybody help please? When I use test class above the code is cover for 92%. The line trigger.new[i].Qualified_By__c = oldUser.id; isn't be coverd. If I change "trigger.new[i].ownerId == trigger.old[i].ownerId" to "trigger.new[i].ownerId != trigger.old[i].ownerId" My test method passed. Error Message:System.DmlException: Update failed. First exception on row 0 with id 00Q2400. But trigger code is 100% coverd. I thnk that I have error in both (trigger and test class).

Any hints would be appreciated.

Edit It shouldn't be written as follows: trigger.new[i].Qualified_By__c = oldUser; because Compile Error: Illegal assignment from User to String. As you wrote in first edit I added all leads to the same list like this list lstLeads = new list(); counter = 1; for (User objUserLGLeadGen : lstUsersLGLeadGen) { Lead objLead = new Lead(LastName='Test_Lead_LGLeadGen'+string.valueof(counter), Status='Working', Company='TestAcc0', OwnerId = objUserLGLeadGen.id); lstLeads.add(objLead); counter++; }

    for (User objUserLGLeadGen : lstUsersLGLeadGen)
    {
        Lead objLead = new Lead(LastName='Test_Lead_LGLeadGen_Neg'+string.valueof(counter), Status='Working', Company='TestAcc0', OwnerId = objUserLGLeadGen.id);
        lstLeads.add(objLead);
        counter++;
    }

    for (User objUserLGLeadGen : lstUsersLGLeadGen)
    {
    Lead objLeadCeo = new Lead(LastName='Test_Lead_CEO', Status='Working', Company='TestAcc0', OwnerId = UserCEO.id);
    lstLeads.add(objLeadCeo);
    counter++;
    }

    System.runAs(lstUsersLGLeadGen[0]) {insert lstLeads;}

After test nothing change.

  • Plz change your question Title it is related to test class. – Ratan Paul Nov 21 '15 at 12:30
  • Hey, shouldn't the following statement be otherwise. i.e. change "trigger.new[i].ownerId == trigger.old[i].ownerId" to != – datmannz Nov 21 '15 at 14:59
0

Welcome to SF.SE. It would have been helpful had you checked your test coverage results and told us which line(s) aren't being covered by your test class.

Your test methods should be split into separate methods between the positive and negative tests. Ditto for the different RunAs methods which leads to where I suspect the source of your problem may lay.

You don't specify a RunAs user for creating any of the test data as well as for the initial test where //trigger will change owners. In not specifying the RunAs user when creating your data or that initial lead, it's very likely that you're not getting coverage on the line below as you'll be failing the conditions necessary to get to it:

trigger.new[j].Qualified_By__c = oldUser.id;

Edit

It would be wise to inser your records using RunAs with a user that has a profile that meets either of the conditions in the if statement below:

if(oldUser.UserRole.Name.contains('LG') || oldUser.UserRole.Name.contains('Lead Gen')){

When you do the following, what you're doing is creating lists for LATER insertion by any RunAs user you choose. You're not inserting them at that time using that user as the RunAs user:

    list<Lead> lstLeads = new list<Lead>();
    counter = 1;
    for (User objUserLGLeadGen : lstUsersLGLeadGen)
    {
        Lead objLead = new Lead(LastName='Test_Lead_LGLeadGen'+string.valueof(counter), Status='Working', Company='TestAcc0', CurrencyIsoCode='USD', OwnerId = objUserLGLeadGen.id);
        lstLeads.add(objLead);
        counter++;
    }

    for (User objUserLGLeadGen : lstUsersLGLeadGen)
    {
        Lead objLead = new Lead(LastName='Test_Lead_LGLeadGen_Neg'+string.valueof(counter), Status='Working', Company='TestAcc0', CurrencyIsoCode='USD', OwnerId = objUserLGLeadGen.id);
        lstLeads.add(objLead);
        counter++;
    }

This last lead creation would seem to be missing a for loop wrapper:

    Lead objLeadCeo = new Lead(LastName='Test_Lead_CEO', Status='Working', Company='TestAcc0', CurrencyIsoCode='USD', OwnerId = UserCEO.id);
    lstLeads.add(objLeadCeo);
    counter++;

You wind up adding all of these to the same list and inserting them here:

System.runAs(lstUsersLGLeadGen[0]) {insert lstLeads;} 

This is one of those cases where having a separate method for creating test data would be beneficial. You then create separate test methods (both positive and negative methods) for each type of user you want to test your trigger with and use the same data for them all. Just be careful to make certain you're using the correct data and users. In this case, I'm not confident that you've properly created your users and the data needed from each type of user.

I suggest you add queries and debug statements to verify your test data following creation, particularly in terms of your users. It would be wise to do the same after insertion of your leads to assure you have the values you think you do. Once you're getting that, you can change the debug statments to assertions.

You can also add debug statements to your trigger to see what you have while debugging this issue as your trigger can and likely will affect the values returned from queries and other debug statements you might have on your data above.

Edit2

I just noticed something that may be the actual cause of your problem. Based on your map, the uncovered statement should be written as follows:

trigger.new[i].Qualified_By__c = oldUser;

You define oldUser to already include the Id, so the statement as you currently have it written cannot be executed, nor can it be referenced. Here's your definition:

User oldUser = mapUsers.get(trigger.old[i].ownerId);
  • The line trigger.new[i].Qualified_By__c = oldUser.id; isn't be coverd – Miloslav Feriančik Nov 22 '15 at 13:56
  • My original answer doesn't change. That's the same line, just with a different iterator being used (i instead of j). It's because you didn't use RunAs to create your test data so the conditions in this line could be satisfied: if((oldUser.UserRole.Name.contains('LG') || oldUser.UserRole.Name.contains('Lead Gen')) && newUser.UserRole.Name.contains('Sales')). – crmprogdev Nov 22 '15 at 14:47
  • Thak you very much for your answer. I know that is same line (I had to change iterator for another error). You wanted to know whic line isn't being coverd, but you had right without this information. I don't know exactly how to create test data to satisfy the condition. Cuold you help me please. – Miloslav Feriančik Nov 22 '15 at 15:39
  • this is not enought?://Test Roles UserRole LGRole = new UserRole(Name='UserAD_Test_LG', ParentRoleId=CEO.id); UserRole LeadGenGRole = new UserRole(Name='UserAD_Test_Lead Gen', ParentRoleId=CEO.id); UserRole SalesRole = new UserRole(Name='UserAD_Test_Sales', ParentRoleId=CEO.id); – Miloslav Feriančik Nov 22 '15 at 15:58
  • See both of my edits. I think the last one nails it for certain. If it doesn't completely fix it, then work on the recommendations from the first edit. – crmprogdev Nov 22 '15 at 18:52

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.