function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Adam Coppin 13Adam Coppin 13 

Apex Test for Invocable Method used in Visual Flow

Hello All,

I created a custom Apex class with invocable method to be able to perform some timezone conversion calculations at a certain point in a Visual Flow.  It works great, but I need to create a test class to get my test coverage above 75% to be able to create a managed package with it.

This is the class with the invokable method:
 
global class TimeZoneConverter
{
    @InvocableMethod(label='Convert Timezone DateTime' description='Converts a date time timezone string to a DateTime value')
    public static List<Datetime> UTCdateValue(List<TimezoneConvertRequest> ConvertMe)
    {
        Timezone tz = Timezone.getTimeZone(ConvertMe[0].tzRequest); //now I have an official Timezone datatype variable tz
        Datetime dt = Datetime.parse(ConvertMe[0].dtRequest.format()); //now I have a UTC Datetime string
        Integer offsetMS = tz.getOffset(dt); //now I have the Milliseconds difference between the timezone selected and the UTC datetime string
        Integer offsetHrs = (((offsetMS / 1000)/60)/60)*-1; //now I have the offset in hours
        
        Datetime adjdt = dt.addHours(offsetHrs); //should be the adjusted value.
        
        List<Datetime> returnMe = new List<Datetime>();
        returnMe.add(adjdt);
        return returnMe;
    }
    
    global class TimezoneConvertRequest {
        @InvocableVariable(required=true)
        public String tzRequest;
        @InvocableVariable(required=true)
        public Datetime dtRequest;
    }

}

and this is as far as I've been able to get with creating the test class:
 
@isTest
	class TimeZoneConverterTest {
        @isTest static void testTimezoneConvertRequest() {
            Test.startTest();
            DateTime BroadcastItemDateTimeTest = Datetime.parse('2016-01-01 13:00:00');
            string Timezone_Selected = 'US/Eastern';
            List<TimeZoneConverter.TimezoneConvertRequest> testingThis = new List<TimeZoneConverter.TimezoneConvertRequest>();
            TimeZoneConverter.TimezoneConvertRequest ConvertMeTest = new TimeZoneConverter.TimezoneConvertRequest();
            ConvertMeTest.tzRequest = Timezone_Selected;
            ConvertMeTest.dtRequest = BroadcastItemDateTimeTest;
            testingThis.add(ConvertMeTest);
            TimeZoneConverter ConvertTest = new TimeZoneConverter();
            ConvertTest.UTCdateValue(TestingThis);
            DateTime testResponse = ConvertTest[0];
			Test.stopTest();
    System.assertEquals(Datetime.parse('2016-01-01 13:00:00'), testResponse);
    }
  }

I'm getting an error of "Static methods cannot be invoked through an Object instance: UTCdateValue(List)" on line 13 - the one that reads:
 
ConvertTest.UTCdateValue(TestingThis);

I've gone around and around on this one and can't find a resource that spells it out quite clearly enough for me... Can someone help me get my code coverage up to snuff?

Thanks!

Adam
Kurt A BrimberryKurt A Brimberry
Hi Adam,  The above code is exactly the sort of thing I have been looking to implement.  Did you ever get any resolution to this?
Adam Coppin 13Adam Coppin 13
Hi Kurt,

Kinda - I didn't get any help here, but was able to eventually figure it out piecing together from a few other sources (now lost to the mists of time).

Here's the text code:
 
@isTest
  class TimeZoneConverterTest {
        @isTest static void testTimezoneConvertRequest() {
            DateTime BroadcastItemDateTimeTest = Datetime.valueOf('2016-01-01 13:00:00'); //Establish the DateTime we're going to pass to the Apex Class
            string Timezone_Selected = 'US/Eastern'; //Establish the timezone we're going to pass to the Apex Class
            List<TimeZoneConverter.TimezoneConvertRequest> testingThis = new List<TimeZoneConverter.TimezoneConvertRequest>(); //Create the object we use during the flow invocing
            TimeZoneConverter.TimezoneConvertRequest ConvertMeTest = new TimeZoneConverter.TimezoneConvertRequest(); //Create the object we pass the information to in the flow
            ConvertMeTest.tzRequest = Timezone_Selected; //Add the Timezone to the data object
            ConvertMeTest.dtRequest = BroadcastItemDateTimeTest; //Add the datetime to the data object
            testingThis.add(ConvertMeTest); //Add the Data Object to the list object
            List<Datetime> testResponse = TimeZoneConverter.UTCdateValue(testingThis); //Pass the list object to the method
        System.assertEquals(Datetime.valueOf('2016-01-01 18:00:00'), testResponse[0]); //Confirm the response matches expectation
    }
  }

Basically, because the method is invocable you have to pass it lists of variables, even if there's only one ever planned to send to it, it has to be in list format.  I was eventually able to figure out the right syntax working in the developer console and looking up each of the error messages I got until they all went away!

I've added comments to each line to hopefully better explain it...

Thanks,

Adam
Marina DennisMarina Dennis

Adam Coppin 13
 

THANK YOUUU SO MUCH. I could not for the life of me figure out how to set the invocable variables for my unit test.... somehow I found your post and you saved me some brain cells and sanity. Kudos!!

Marco Ivan Mejia VeraMarco Ivan Mejia Vera

Adam Coppin 13

Thank you! I don't consider myself a developer, and I've been trying to create a test class for hours, thanks to this publication I was able to do it in minutes!