2

I have a custom controller used for VF page and in the controller constructor I am fetching a report Id. Functionality is working as expected. I am basically fetching the report Id and showing it as a link on the VF page. Now I am writing the test class for this, and not able find a way to pass the report id to the constructor of the controller from test class.

Error I am getting is

"System.NullPointerException: Attempt to de-reference a null object".

Test Class: ..... .....

AccountSalesController testSalesAccSearch =new AccountSalesController (new ApexPages.StandardController(account));
  //testSalesAccSearch.myaccid = '00O63000000KsKZEA0';

..... .....

VF Code:

<apex:pageBlock title="Reports">
        <apex:pageBlockSection >
            <apex:outputLink value="/{!myaccid}" id="MyAcc">My Accounts</apex:outputLink><tr></tr>
        </apex:pageBlockSection>
    </apex:pageBlock>

Controller Constructor:

public AccountSalesController (ApexPages.StandardController controller) {

myaccid = [SELECT ID FROM report WHERE developerName='Active_Sales_Accounts' and FolderName = 'Sales Reports'].id;

  }
0

2 Answers 2

2

You can change the Controller class to handle reporting scenario like this, introducing Test.isRunningTest() and refer any standard reports which are always be available in SFDC instance.

Controller

public AccountSalesController (ApexPages.StandardController controller) {

    String reportName = null;
    String folderName = 'Sales Reports';
    if(Test.isRunningTest())
    {
        reportName = '<any standard SFDC report>'; //like 'Sales By Account'
    }
    else
    {
        reportName = 'Active_Sales_Accounts';
    }
    myaccid = [SELECT ID FROM report WHERE developerName=:reportName and FolderName =:folderName].id;

 }

Test Class

Account acct = new Account(Name='testAccount');  
insert acct;
PageReference page = Page.MyVFP;
Test.setCurrentPage(page);
ApexPages.currentPage().getParameters().put('id',acct.Id);

ApexPages.StandardController standrdcontroller = new ApexPages.StandardController(acct);
AccountSalesController myController = new AccountSalesController(standrdcontroller);
System.assertEquals(.....);
1
  • 1
    Alternatively, one might use SOSL to perform a search for the record, and then in the unit test set the fixed search results to a desired value. This would leave your controller free of test code and covered 100%. I prefer to avoid having Test.isRunningTest() in live code when possible.
    – sfdcfox
    Apr 21, 2017 at 8:55
1

This is one of those classic scenarios where you have to use SeeAllData=true in your test class.

The issue is that your query -

SELECT ID FROM report WHERE developerName='Active_Sales_Accounts' and FolderName = 'Sales Reports'

is not fetching any records(means returning null) and then you are trying to access its ID which is obviously resulting into Null-pointer exception.

The bad news is that you can not create Report in Unit Test Class using apex. So only way I can think of is to use (SeeAllData=true) for your test class and make sure you rely on this for only the Report query and no other object.

@IsTest(SeeAllData=true)
public class MyTestClass
{
  ...
}
6
  • it is not needed for reports as @SeeAllData is ignored for testing of reports Apr 21, 2017 at 5:11
  • I just tried it in my org and I was able to get Report data using SeeAllData=true. Am I missing something? Apr 21, 2017 at 5:27
  • Refer this developer.salesforce.com/docs/atlas.en-us.apexcode.meta/… for more explanations Apr 21, 2017 at 5:28
  • this is also fail during production deployment if report doesn't exist Apr 21, 2017 at 5:30
  • Yes, that can be handled using Test.isRunningTest but any query on Report will return no rows if used with SeeAllData=false in a Test class. The link talks about running a report in test class i.e report runs always ignore the SeeAllData annotation. Apr 21, 2017 at 5:43

You must log in to answer this question.

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