You need to sign in to do that
Don't have an account?
Ken_Koellner
Callouts from classes invoked from runtests
I imported some WSDL to get stubs and wrote a class that successfully class them when testing interactively.
I'm now writing Apex tests and my first test that calls Apex methods that will eventually get into methods that do callouts is failing with an exception.
Are the any specific techniques that are needed to get Apex test methods to run when callouts are invoked?
I printed out the cause of the exception --
System.TypeException: Methods defined as TestMethod do not support Web service callouts, test skipped
So obviosly you can't get callouts to work.
Is there some technique to work-around this and simulate callouts in testing?
I found this paper -- http://wiki.developerforce.com/index.php/An_Introduction_to_Apex_Code_Test_Methods
But I think the technique there doesn't help.
I need to test several layers of business logic that sit on top of methods that are wrappers for callouts. The business logic relies on those methods being there.
I don't know if there's any way to detect test mode and conditionally not do the callout in the web service and instead, simulate data.
Yes You can achieve this.
set a property isTestMode in your class like
public boolean isTestMode
{get;set;}
check like this wherever you are using callouts
if(!isTest)//if isTest is false
//callout process
else
//nothing
set isTest to true in your test method. This will make sure your callout method does not get called.
Cheers
That seems like a viable technique. We put our tests in separately classes but that doesn't meed it could be public and then in the test class do --
MyClassThatDoesCallOut.isTestMode = true;
What I ended up doing is using certain key values to indicate tests. All the callouts I have look up data from other systems. I have wrappers around my callouts anyway and I put in tests for key values beginning with "ZZTEST". If the key is like that, it transfer to a simulate method. I can use different key values to get different results like ZZTESTNF will end up with a not found. ZZTESTZ3 will return three results, etc.
What would be cool is if Apex had function pointers, then in test mode, rather than just setting a flag, I'd pass in a pointer to method that does the simulate, the wrapper could then call back to the test class.
Hey,
Be sure to check out http://wiki.developerforce.com/index.php/An_Introduction_to_Apex_Code_Test_Methods page, it has a lot of info and some good practices on how to test Callouts.
Hope this helps,
Gaston.
I already sited that paper above. I found the case about callouts in the paper pretty much worthless.
Its not worthless, if you follow the pattern there
You can create test methods that do the following:
So you can simulate the data and test the creation of the request and the processing.
You cant do callouts in test methods, so this is the best way to cover as much code and methods as possible.
Ive tested all kinds of callouts following this method, and inside the testmethod having a String with the xml/whatever returned there.
Im sorry if im not following you, but this seems to be the way you need to test your methods, if not could you elaborate more on why this does not apply?
Thanks,
Gaston.
This is is not covering the logic that deals with the callout requests. The issue is covering all the business logic that relies on the callout. I'm using webService callouts so there's no prep and response code to cover. Everything having to do with the call out is a single line (except for getting the stub).
The code is like --
businessMethodA calls BusinessMethodB calls BusinessMethodC.
BusinessMethod C does the call out,.
I have to get coverated on the A, B, and C methods. The testmethod is going to call businessMethodA. Were the call out would take place in method C, something has to simulate the callout so that methods A, B, and C have data to operate on.
The techniqe in the manual has the callout in the test method itself and comments it out. that doesn't do any good for all the layers on top that may use the callout.
I am sorry if it is a lengthy response. All you have to do is divide your call outs to buildrequest, invokerequest, handlerequest and handle your code..
I have done this before for Authorize.net web service call outs..
Inside your class:
Test method:
Let me know if this is useful at all to you.
Thanks
Hi Ken,
To simulate your callout in your test method you should first of all, adjust your apex class (where you execute the callout) taking care of this:
1. Create a public boolean variable in your class that works like a flag, let this class being able to know when to run the callout and when not.
2. Create a public "Response" variable to set a simulated response.
3. Include logic to your class that works according to the flag of point 1.
Later, in your testMethod invoke the RESPONSE (of your apex class) and set the kind of response you need to test, set the flag value and call the apex class method that executes the callout.
See the following example:
Apex Class (the one that runs the callout)
Apex TestMethod
I hope this info and example help you.
Regards,
Wilmer
Wilmer, that's pretty much what I did except I keyed it off an input parameter. Certain values can't exist in real datal so the testmethod passes in values like ZZTEST123 which are detect in the low-level method an shunted to a simulate method.