0

I have written the below trigger and helper class. I am a newbie and pieced the trigger and class together with help from various forms. It works fine in sandbox but I have no idea how to write the test class so I can deploy to production. I have 4 almost identical triggers (except for group names) and 1 helper class

Trigger

trigger Addtogroup1 on Contact (after insert, after update) {

      List<GroupMember> GMlist = new List<GroupMember>();
       Set<String> contactEmails = new Set<String>();
       for(Contact con : Trigger.New) {
          //create a set with the contact email addresses
          contactEmails.add(con.email);
       }

       //query for the related users and put them in a map,
       //where the key is the email and the value is the user
       Map<String, User> emailUserMap = new Map<String, User> ();
       for(User aUser : [select id, email from User where email in : contactEmails]){
          emailUserMap.put(aUser.email, aUser);
       }
           system.debug(emailUserMap);
           List<Id> userIdList = new List<Id>();
      for(Contact con : Trigger.New) {
        if(con.Public_Group_Service_Partner_Content1__c == TRUE) {    

             userIdList.add(emailUserMap.get(con.email).id);

          }
      }  

      //dymanically get the get group id.
      Group theGroup = [select id from Group where Name = 'Service Partner Content'];
      if(null != theGroup){
          //call the contact trigger helper if the group exists. 
          //This method adds the user to the group
          ContactTriggerHelper.addUsersToGroup(theGroup.id,userIdList );
      }
  }

Helper Class

public class ContactTriggerHelper{

  //future call to do the group adding.  the future call will spawn a new thread.
  @future
  public static void addUsersToGroup(String groupId, List<Id> userIds){
      List<GroupMember> GMlist = new List<GroupMember>();
      for(ID userId: userIds){
          GroupMember gm = new GroupMember();
          gm.GroupId = groupId;
          gm.UserOrGroupId = userId;
          gmList.add(GM);
      }


      if(gmList.size() > 0){
          insert gmList;
      }
  }

}

I tried using this test class

@isTest

private class AddtoGroupTest
{
    static void createGroup(Boolean isGroup)
    {

        // Insert contact with your required field.

        Contact cnt = new Contact();
        cnt.LastName = 'Test contact';
        cnt.Email = 'test@test.com';
        cnt.Public_Group_Technology_Partner_Content__c = true;
        insert cnt;

        // Insert user

        Profile p = [SELECT Id FROM Profile WHERE Name='System Administrator'];
        User u = new User(Alias = 'standt', Email='test@test.com',
        EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
        LocaleSidKey='en_US', ProfileId = p.Id,
        TimeZoneSidKey='America/Los_Angeles', UserName='standarduser@testorg.com');
        insert u;

        // Insert Group
        if(isGroup == true)
        {
            Group grp = new Group();
            grp.Name = 'Technology Partner Content';
            grp.DeveloperName = 'Technology Partner Content';
            insert grp;
        }
    }



    static testMethod void insertWithGroup()
    {
        createGroup(true);
    }

    static testMethod void insertWithoutGroup()
    {
        createGroup(false);
    }
}

But I got this error

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, Addtogroup4: execution of AfterInsert

caused by: System.NullPointerException: Attempt to de-reference a null object

Trigger.Addtogroup4: line 21, column 1: []

Again I am a newbie and have no idea how to correct this or if I am on the right path with the test class so if anyone could show me what it should look like I would greatly appreciate it.

1

These are few notes for writing code/tests that might help you:

  • Use variable names so it is clear what they contain. It is not relevant to know if it is a map or set or a list.

  • Use name convention for triggers/classes/etc. as already defined by best practices (check online for more resources).

  • Before accessing an object property (ie user.id), check the object is not null.

  • When testing future methods, call it or create data that calls it in Test.startTest() and Test.stopTest(), and after that assert expected behaviour.

  • I noticed that you are calling methods, but not asserting (verifying) expected results. Tests must use asserts. Also aim for 100% coverage not the minimum coverage required. When testing, I follow the next approach:

a) setup data,

b) act (call the methods) and

c) assert that output is as expected.

Just calling methods to have the minimal code coverage is not testing.

This is my attempt to write the above trigger:

trigger ContactAddUserToGroup on Contact (after insert, after update) {
       List<GroupMember> groupMembers = new List<GroupMember>();
       Set<String> contactEmails = new Set<String>();
       Map<String, User> usersByEmail = new Map<String, User>();
       List<Id> userIds = new List<Id>();

       for (Contact c : Trigger.New) {
          contactEmails.add(c.email);
       }

       for (User u : [SELECT id, email FROM User WHERE email IN :contactEmails]){
          usersByEmail.put(u.email, u);
       }

      for (Contact c : Trigger.New) {
        if (c.Public_Group_Service_Partner_Content1__c == true && 
            usersByEmail.containsKey(c.email)
          ) { 
             userIds.add(usersByEmail.get(c.email).id);
          }
      }  

      Group group = [SELECT id FROM Group WHERE Name = 'Service Partner Content'];
      if (group != null) {
          ContactTriggerHelper.addUsersToGroup(group.id, userIds);
      }
  }

Hope this helps.

0

This error has occured because in the line userIdList.add(emailUserMap.get(con.email).id); there is no value in the map emailUserMap corresponding to the contact email key.

Also there are some changes to be made in the code. 1) Before adding a specific value to set check if the value is null. In this case , before adding contact email to contactEmails set check if the field has value in it and then add it 2) Before querying based on a set, check if the set has values in it and then proceed. in this case the code can be written as

if(contactEmails.size()>0) List userDetails=[select id, email from User where email in : contactEmails];

if(userDetails.size()>0){ Map emailUserMap = new Map (); for(User aUser :userDetails ){ emailUserMap.put(aUser.email, aUser); } }

In the test class, insert the user first and then insert the contact with the user's email in the contact email field

0

The error mentions "AddtoGroup4" but your posted code only mentions AddtoGroup1. Can you post AddtoGroup4 as well? Also, in your test class, try adding an account first, then your contact.

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.