3

I have a custom button that calls an apex class - and per this tutorial the class is a "Web Service" (but not in the classic sense).

5 days ago in production the test class (and 21 others) started to fail with this error: Methods defined as TestMethod do not support Web service callouts. The test class passed on February 22, 2016 - well after the Winter '16 release when (as I've seen) some tests of this type are no longer "skipped" but "fail." That doesn't explain why (when nothing else significant in the org has changed) there are 21 failures like this.

Any help would be appreciated - again, these test classes simply simulate creating a record for the object that the custom button exists for, then "clicking" that button by calling the class method.

global class ButtonCallsNew { 
 // This button click calcs new vals based on biz rules 
 WebService static String ReallocateRemainingHours(String strPrjID) { 
 // Read Proj estimates 
  pse__Proj__c prj = [SELECT ID, Name, pse__Stage__c, pse__End_Date__c, Estimated_Hours_Remaining__c FROM pse__Proj__c WHERE ID=:strPrjID]; 

Test class

public static testMethod void testReallocate() { 
//set up variables/constants then run as the established user 
 System.runAs(usr) { 
 //Create and insert records //this line calls the class that “clicks” the button rc = ButtonCallsNew.ReallocateRemainingHours(prj.ID);
  • Unless the entire test class and code is examined it's hard to suggest anything or help you debug – Mohith Shrivastava Feb 27 '16 at 23:37
  • Apologies - I'm new to posting questions here, and the class is far to large to post to the comments. I don't see any way to upload a file. How should I share the code and test class? FYI it's the same exact process that the link I posted in the question (the "tutorial" in the first sentence) walks you through. Create a class and call it from a custom button - so you have to turn it into a "Web Service." – Ken Feb 28 '16 at 0:11
  • First of all no apologies please .You can just put test class method thats causing issue and also the apex method that errored out in main class – Mohith Shrivastava Feb 28 '16 at 0:12
  • If a trigger could be fired from a custom button click I'd have done instead. There is no callout to any external system. The class: Global class ButtonCallsNew { // This button click calcs new vals based on biz rules WebService static String ReallocateRemainingHours(String strPrjID) { // Read Proj estimates pse__Proj__c prj = [SELECT ID, Name, pse__Stage__c, pse__End_Date__c, Estimated_Hours_Remaining__c FROM pse__Proj__c WHERE ID=:strPrjID]; //Business logic follows to calculate and write a value to a field on a custom object…. – Ken Feb 28 '16 at 0:33
  • The test method: public static testMethod void testReallocate() { //set up variables/constants then run as the established user System.runAs(usr) { //Create and insert records //this line calls the class that “clicks” the button rc = ButtonCallsNew.ReallocateRemainingHours(prj.ID); – Ken Feb 28 '16 at 0:34
2

Since from recent release any class implementing webservice now requires you to implement mock callout ,unfortunately you will need to do this for all classes failing .This has been recent change.

Just to help you started I have added code snippets .Once you implement mock interface you should be able to satisfy code coverage .Also I understand that its JS button call and you are not calling webservice but still you will have to write mock classes .

global class ButtonCallsNew { 
// This button click calcs new vals based on biz rules 
 WebService static String ReallocateRemainingHours(String strPrjID) { 
     return strPrjID ;
  }
}

The mock class will be as below

global class ButtonCallsNewMockImpl implements WebServiceMock {
 global void doInvoke(
       Object stub,
       Object request,
       Map<String, Object> response,
       String endpoint,
       String soapAction,
       String requestName,
       String responseNS,
       String responseName,
       String responseType) {

    // Create response element from the autogenerated class.
    // Populate response element.
    // Add response element to the response parameter, as follows:
    response.put('response_x', 'test'); 
    }
 }

The test class will be as below

 @isTest
  private  class testReallocate { 
   @isTest 
   static void testEchoString() {  
     Test.setMock(WebServiceMock.class, new ButtonCallsNewMockImpl());
        String s = ButtonCallsNew.ReallocateRemainingHours('test');
        system.assertEquals(s,'test');
   }
 }
  • Mohith- I very much appreciate your help. What I don't understand is: 1) my class does not make a webservice callout - it's just instantiated as a "WebService" because the documentation says I have to in order to fire logic from a custom button. 2) The classes all passed just days ago on Feb 22. There has not been a major release since then. 3) I am not at all experienced with WebServices, and the code in your answer is exactly the same stubbed-out code in the docs referenced - I don't know enough to fill out "// Create response element from the autogenerated class." – Ken Feb 28 '16 at 15:29
  • Ken ,I understand you don't call webservices externally .The same code I tried by creating a button and it works. You don't have to worry about anything in the class just return a string . – Mohith Shrivastava Feb 28 '16 at 15:41
  • Mohith, there is something strange going on. Classes that don't pass in production DO pass in a sandbox - the code is exactly the same. In another unrelated org the same approach works in the sandbox AND in production. I have no idea how to trace this but have opened a case with SF support...... – Ken Feb 28 '16 at 15:49
0

Here's the docs on how to solve your problem.

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_callouts_wsdl2apex_testing.htm

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.