3

Anybody know how to set the lastlogindate field on User for a test class?

Here is my scheduled apex class. I need to create a user with a lastlogindate more than 60 days ago in order to get 100% code coverage.

Edited - working code

   public class  sched_Freeze_60Day_Users implements Schedulable {

    @TestVisible static Date threshold = date.today().addDays(-60);

    //Make class schedulable    
    public void execute(SchedulableContext ctx) {        

        Profile p = [SELECT Id FROM Profile WHERE Name = 'Chatter Only - External Client']; 

        //Find external users who have been inactive for sixty days.
        List<UserLogin> uLogins = [
            SELECT ID FROM UserLogin
            WHERE UserId IN (Select Id
                             FROM User 
                             WHERE LastLoginDate <= :threshold
                             AND ProfileId = :p.Id
                            )
            AND isFrozen = FALSE
        ];

        //Freeze any user accounts that were found. 
        if(uLogins.size()>0){
            for(UserLogin u:uLogins){
                u.IsFrozen = TRUE;
                    }

            update uLogins;            
        }

    } //end schedudle class
} //end main class

* test class *

@isTest
public class test_sched_freeze_60day_users {

    // CRON expression: midnight on March 15.
    // Because this is a test, job executes
    // immediately after Test.stopTest().
    public static String CRON_EXP = '0 0 0 15 3 ? 2022';


    @testSetup static void setupTestData(){

        //Create Testing Users
        User thisUser = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()];
        System.runAs (thisUser) {
            InsertTestUsers.InsertUsers();
        }

    }


    static testmethod void test() {

        sched_Freeze_60Day_Users.threshold = Date.today();

        Test.startTest();

        // Schedule the test job
        String jobId = System.schedule('ScheduleApexClassTest',
                                       CRON_EXP, 
                                       new sched_Freeze_60Day_Users());

        // Get the information from the CronTrigger API object
        CronTrigger ct = [SELECT Id, CronExpression, TimesTriggered, 
                          NextFireTime
                          FROM CronTrigger WHERE id = :jobId];

        // Verify the expressions are the same
        System.assertEquals(CRON_EXP, 
                            ct.CronExpression);

        // Verify the job has not run
        System.assertEquals(0, ct.TimesTriggered);

        // Verify the next time the job will run
        System.assertEquals('2022-03-15 00:00:00', 
                            String.valueOf(ct.NextFireTime));

        Test.stopTest();
    }        
}
  • 1
    Have you tried either of the methods suggested in this help article? – Derek F Sep 20 '16 at 14:17
  • @adrianlarsen Adrian, your solution got deleted for some reason. I got enough of it however I think to get me on the right path. – Matt M Sep 20 '16 at 14:46
  • I deleted it because I had my doubts. I can leave it here if you prefer that. I think finding a way to set the fields may be the right choice here though. – Adrian Larson Sep 20 '16 at 14:56
2

I would recommend an alternative. Make your sixtyDaysAgo variable writable in a test context. Also, never use global. Usage of public should nearly always suffice unless you are working on a Managed Package.

public class MyScheduler
{
    @TestVisible static Date threshold = Date.today().addDays(-60);
    public static List<UserLogin> getUserLogins()
    {
        return [SELECT Id FROM UserLogin WHERE Id IN (
            SELECT Id FROM User WHERE LastLoginDate <= :threshold AND ...
        ];
    }
}

Your test class can then just set it to today.

static testMethod void testFindUser
{
    MyScheduler.threshold = Date.today();
    // run code
}
|improve this answer|||||
  • Ok, new code for me, are you saying that in my schedule apex class I can create a variable with the annotation of @testvisible? – Matt M Sep 20 '16 at 14:25
  • That's what I'm saying, yep. And you can make a separate method dedicated to getting the UserLogin records. Although I'd think it might be null for users you create in your test. Might not work. Hmm... – Adrian Larson Sep 20 '16 at 14:27
  • I updated my original post with working code. I am getting 100% code coverage. – Matt M Sep 20 '16 at 15:01

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.