+ Start a Discussion
Keith987Keith987 

Best way to delay until time changes in a test?

I have some logic that relies on the Last Modified Date of an SObject and so in my tests need to create objects where these dates reliably differ. Given that AFAIK there is no sleep method available I am using the code below to idle away time but would be interested to know if anyone has found a better approach e.g. an API call that reliable takes many milliseconds to execute and so provides a better "delay per script statement" ratio?

 

Thanks,

Keith

 

private static void delayUntilTimeChanged() {

    Integer msPerS = 1000;
    Datetime start = Datetime.now();
    Datetime current = Datetime.now();

    // No sleep available so this ugliness
    Integer counter = 0;
    while ((current.getTime() / msPerS) == (start.getTime() / msPerS)) {
        
        // This code takes about 250ms or more on na3
        Long t1 = System.currentTimeMillis();
        String bigRandomString = '';
        for (Integer i = 0; i < 2000; i++) {
            bigRandomString += Crypto.getRandomLong();
        }
        for (Integer i = 0; i < 50; i++) {
            Blob cryptoKey = Crypto.generateAesKey(256);
            Blob data = Blob.valueOf(bigRandomString);
            Blob encryptedData = Crypto.encryptWithManagedIV('AES256', cryptoKey, data);
            Blob decryptedData = Crypto.decryptWithManagedIV('AES256', cryptoKey, encryptedData);
        }
        Long t2 = System.currentTimeMillis();

        System.debug('>>> delayUntilTimeChanged delayed for ' + (t2 - t1) + ' ms'
                + ', Count ' + counter
                + ', ScriptStatements ' + Limits.getScriptStatements() + ' of ' + Limits.getLimitScriptStatements()
                + ', CpuTime ' + Limits.getCpuTime() + ' of ' + Limits.getLimitCpuTime()
                );
        
        counter++;
        current = Datetime.now();
    }
}

 

virtcoudvirtcoud

What if you put your object creates in separate @future calls from your test (would give you some degree of time separation)?   CPU consuming attempts to implement a sleep function can be a bit dicey in a muti-tenant cloud...  Would this work for your test? 

dmchengdmcheng

When I run into situations where it's very difficult or impossible to replicate the conditions needed to test a code section, I just force the code to run if it detects unit test is currently running, something like this:

 

if(Contact.LastModifiedDate < date.today().addDays(-30) || Test.isRunningTest()) {

 

Very ugly, but it gets the code coverage ...

Martha_SenetaMartha_Seneta
Here is a sleep workaround I've used:

Long startingTime = System.now().getTime(); // Num milliseconds since Jan 1 1970
Integer delayInMilliseconds = 1000; // One-second delay
while (System.now().getTime() - startingTime < delayInMilliseconds)  {
            // Do nothing until desired delay has passed
}