To start, let's say I have this simple unit test:
@isTest
public static void shouldCallFutureMethod() {
Test.startTest();
System.enqueueJob(myQueueableJob);
Test.stopTest();
}
Given certain conditions, when I run myQueueableJob.execute(), then the execute() function will in turn call a separate function which is annotated with @Future because it makes a callout. Let's call that @Future function makeCallout().
I understand that in the above unit test, I cannot run any asserts that depend on the behavior of the makeCallout() function. That's fine. What I want to do is assert that the makeCallout() function has been queued, and assert the state of the parameters with which it was called. For example, if makeCallout() has a parameter X, I want to do the following:
@isTest
public static void shouldCallFutureMethod() {
Test.startTest();
System.enqueueJob(myQueueableJob);
Test.stopTest();
Assert.isTrue(/* makeCallout(X) was called once */);
Assert.areEqual(SOME_NUMBER, X);
}
In a different programming language, I might write an interface that defines the makeCallout() function then implement that interface in a test class that simply stores X so I can check its value in the unit test. Unfortunately, since a @Future function has to be static in Apex, I can't define the function in an interface and override it in an implementation.
Additionally, I've seen that the AsyncApexJob table is supposed to have information about the async jobs that have been queued, but when I've tried querying it after the Test.stopTest() call, I noticed that all of the MethodName fields of each record in that table are null. So I can't assert which method was called. Furthermore, I don't see any way to access the parameters with which it was called.
Can anyone help? The specific restrictions of Apex seem like they are designed in such a way that will prevent me from writing a real test for this functionality.