0

I have a Flow which calls an apex class (via action). The purpose of the action is to grab a list of Lead Id's from a specific report. The reportID is passed to the class from the flow. Then, the class returns the list of Id's to the flow. The class being called by the flow is:

global class createRecruiting{

  @InvocableMethod
  public static List<methodOutputs> createCandidacy(List<String> incomingReport){
    List <Report> reportList = [SELECT Id,DeveloperName FROM Report WHERE Id =:incomingReport[0]];
    String reportId = (String)reportList.get(0).get('Id');
    Set<ID> leads = new Set<ID>();
    Integer recCount = 0;
    methodOutputs fo = new methodOutputs();


    // Run the report synchronously
    Reports.reportResults results = Reports.ReportManager.runReport(reportId, true);
    // Get the first down-grouping in the report
    Reports.Dimension dim = results.getGroupingsDown();
    integer groupSize = dim.getGroupings().size();

    // Iterate through results, add each ID to the set.
    for (Integer i = 0; i < groupSize; i++) {
      Reports.GroupingValue groupingVal = dim.getGroupings()[i]; 
      leads.add(groupingVal.getValue().toString());
      RecCount++;       
    }

    // Query the lead records from the report
    List<Lead> ll = [SELECT Name, Id FROM Lead WHERE Id IN :leads];

    fo.leadList = ll;
    fo.recordCount = RecCount;
    List<MethodOutputs> theResults = new List<MethodOutputs>();
        theResults.add(fo) ;
        return theResults;
  }

  public class methodOutputs{
    @InvocableVariable 
    public List<Lead> leadList;

    @InvocableVariable
    public integer recordCount;
  }


}

I'm unable to figure out how to write a test class for this scenario. Here's what I have, which results in a method does not exist / incorrect signature error:

    @isTest
    public class createRecruitingTest{

    @isTest(SeeAllData='true')
    public static void testCreateCandidacy() {

      // Create a Lead Object which is what the report is based on.
      Lead l = new Lead(LastName='ApexTestLead', Status='New', Company='Test Company');
      insert l;


     //Create the report ID to be passed into the class.
      List <Report> reportList = [SELECT Id,DeveloperName FROM Report where
          DeveloperName = 'Evergreens_Report_aXW'];
      String reportId = (String)reportList.get(0).get('Id');

    //Execute test.  I've not made assertions yet, but the assertion would
    //be simply that a lead list with size > 0 is returned.  
        Test.startTest();
        createRecruiting testCreateRecruiting = new createRecruiting();
        testCreateRecruiting.createCandidacy(reportList);
        Test.stopTest();

    }
} 

I have the feeling I'm going about this all wrong. Can anyone help me identify how to obtain code coverage when using the report namespace?

1 Answer 1

1

The method you're trying to test has the following signature:

createCandidacy(List<String> incomingReport)

Your test code is attempting to pass a List<Report> to the method instead of a List<String>. Looks like you probably wanted to do something like createCandidacy(new List<String>{reportId});

Beyond that, you should probably consider using seeAllData=false1 and create the required data for your test inside of the test class itself. Also, don't forget to put in some assertions to verify that the output/side effects of running your method conforms to your expectations.

1: I know that there are some situations where seeAllData=true is required, but I'm not sure if this is one of them. seeAllData=false is the general recommendation, and is correct 99% of the time, so that's what I'm going with.

1
  • 2
    The Reports and Dashboards API runs with inherent seeAllData=true, which makes the picture a bit complicated. I could see an argument for annotating the test class to make clear that the entire test is affected by org data.
    – David Reed
    Commented Oct 13, 2019 at 17:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .