0

I'm working on a test method for a trigger that I wrote that when a user is deactivated it sends an email to the manager. My problem is that in my test I populate the ManagerId field but the test doesn't recognize it and stops the process. If I update the User record it works but that's hitting other logic making it hard to test.

logic:

public static void filter(Map<Id, User> oldMap, Map<Id, User> newMap)
{
    Set<Id> users = new Set<Id>();

    for(User u : newMap.values())
    {
        if(
            u.IsActive != oldMap.get(u.Id).IsActive &&
            u.IsActive == false &&
            u.UserType == 'Standard' &&
            u.ManagerId != null
        )
        {
            users.add(u.Id);
        }
    }
    if(users.size() > 0)
    {
        actions(users);
    }
}

Test:

@TestSetup
static void makeData()
{
    User testUser = NPD_Utilities.createTestUser();
}

@IsTest
static void testNoRecords()
{
    User u = [SELECT Id, UserType, ManagerId, IsActive, ProfileId FROM User WHERE Name = 'Testing User'];   
    Map<Id, User> oldmap = new Map<Id, User>();
    Map<Id, User> newMap = new Map<Id, User>();

    oldmap.put(u.Id, u);

    User uNew = new User();
        uNew.Id = u.Id;
        uNew.IsActive = false;
        uNew.ProfileId = u.ProfileId;
        unew.ManagerId = UserInfo.getUserId();
        uNew.Deactivated_Date__c = System.today();
        uNew.Deactivated_Reason__c = 'MacMaster';

    newMap.put(uNew.Id, uNew);    

    Test.startTest();
        //update uNew;
        NPD_UserDeactivationAlert.filter(oldMap, newMap);
    Test.stopTest();                
}

I am trying to get it past the managerid line:

enter image description here

Where am I going wrong?

  • What is the UserType of your testing user? Are they active? – Adrian Larson Dec 26 '19 at 16:44
  • It's Standard, userType is not a writeabile field so I tried to work around it by setting the profileId which is only available to standard users. – Dan Wooding Dec 26 '19 at 16:51
0

The root cause was not the ManagerId as I had questioned but the UserType was null because I never did any dml to populate the temp user. UserType is not writable so you can't just populate it and hope for the best but query for it.

When doing a test with old and new records I've found that you cannot take a SObject and then update some fields and have it work. Example does not work (using account because there are less fields):

Account acc = new Account();
acc.Name = 'Dan test';
insert acc;

Account a = [SELECT Id, Name FROM Account];
oldmap.put(a.Id, a);

a.Name = 'Jim test';
newMap.put(a.Id, a);

The record a still has 'Dan Test' in both maps even though I updated a.Name to be Jim.

I've found if I create a new instance of the record I can set it and it will work:

Account acc = new Account();
acc.Name = 'Dan test';
insert acc;

Account a = [SELECT Id, Name FROM Account];
oldmap.put(a.Id, a);

Account a2 = new Account();
a2.Id = a.Id
a2.Name = 'Jim test';

newMap.put(a2.Id, a2);

Now the records have the correct names and can be compared.

For Users in this example it is different because UserType cannot be set on the record. If you create a new User record instance you cannot set UserType, and as we see in the example you cannot just update the User that we queried.

So how can we get around this? By cloning the record. This creates a new User to work with while still preserving key fields that we need to be populated like UserType.

This test now runs through the filter method as expected because all fields are populated.

@IsTest
static void testNoRecords()
{
    User u = [SELECT Id, UserType, ManagerId, IsActive, ProfileId FROM User WHERE Name = 'Testing User'];   
    Map<Id, User> oldmap = new Map<Id, User>();
    Map<Id, User> newMap = new Map<Id, User>();

    oldmap.put(u.Id, u);

    User uNew = u.clone(true, true);
        uNew.IsActive = false;
        unew.ManagerId = UserInfo.getUserId();
        uNew.Deactivated_Date__c = System.today();
        uNew.Deactivated_Reason__c = 'MacMaster';
    newMap.put(uNew.Id, uNew);    

    Test.startTest();
        NPD_UserDeactivationAlert.filter(oldMap, newMap);
    Test.stopTest();                
}
  • Was just about to answer this. Did doing the first method not work in User (editing the sObject directly before putting in map)? It seemed to show the changes in my anonymous script even with putting it in a map – Kris Goncalves Dec 26 '19 at 17:26
  • For me when I updated isActive and then put it in a different map it updated in both maps. Maybe that's how it's supposed to work. – Dan Wooding Dec 26 '19 at 18:27

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.