-2

I am trying to build a test class on the following, but keep running into the error message “Method does not exist or incorrect signature: void setPageSize(Integer) from the type MyNewCaseListController” It is coming from the 19th line in the test class. Any ideas what I am doing wrong? I am also getting the same type of error with controller.setFilterId(filter); and controller.setFilterId(listView.getValue());.

Here is my class:

public with sharing class MyNewCaseListController {
    public MyNewCaseListController(ApexPages.StandardSetController  ctrl){
        string filter = ApexPages.currentPage().getParameters().get('filterId');
        ctrl.setPageSize(50);
        List<System.SelectOption> listViews = ctrl.getListViewOptions();
        if (filter != null) {
            ctrl.setFilterId(filter);
        }
        else {
            for(System.SelectOption listView : listViews)
            {
                if (listView.getLabel() == 'Recently Viewed Cases') 
                    ctrl.setFilterId(listView.getValue());
            }
        }
    }
}

Here is my test class:

@isTest public without sharing class MyNewCaseListControllerTest {
    @isTest public static void TestMyNewCaseListController(){
        
        List<Case> Cases = new List<Case>();
        for(integer i=0; i<20; i++){
            Case ca = new Case();
            ca.Subject = 'Test Subject - Field Test ' + i;
            ca.Description = 'Test Description - Field Test ' + i;
            ca.Origin = 'Web Email';
            ca.Type = 'Other';
        }
           
        Test.startTest();
        insert Cases;
        MyNewCaseListController controller  = new MyNewCaseListController(new ApexPages.StandardSetController(Cases));

      
        
        string filter = ApexPages.currentPage().getParameters().get('filterId');
        controller.setPageSize(50);
        
        List<System.SelectOption> listViews = ctrl.getListViewOptions();

        // Set Filter Id if passed in parameter
        if (filter != null) {
            ctrl.setFilterId(filter);
        }
        else {
            for(System.SelectOption listView : listViews)
            {
                if (listView.getLabel() == 'Recently Viewed Cases') 
                    ctrl.setFilterId(listView.getValue());
            }
        }
    }
}
8
  • 1
    Your controller encapsulates rather than extends the standard set controller. It doesn't have these methods on it. You need to get the standard controller from your controller...
    – Phil W
    Commented Dec 9, 2022 at 15:47
  • @Phil W, thanks, but not sure I understand. The documentation on Apex.StandardSetController says it has these methods. The code in the class works fine with these methods. I am still very new to Apex so maybe I just don't understand what you are saying. But if I do need to get the standard controller from the controller, how would I do that? Commented Dec 9, 2022 at 16:50
  • @Phil W, I commented out all the controller methods and tried to find the value of controller and it is now saying that when I do a system.debug(controller) "The expression cannot be assigned". Is this part of what you were talking about? Commented Dec 9, 2022 at 17:01
  • Your controller receives the standard controller through a constructor parameter. You can store this in an attribute of your controller then call the methods you need on that.
    – Phil W
    Commented Dec 9, 2022 at 17:11
  • @ Phil W sorry still very very new. When you say "Your controller (meaning the thing I called controller) receives the standard controller (ApexPages.StandardSetController) through a constructor parameter." What is the constructor parameter? And by storing it in an attribute are you saying I would do something like controller.first = someVariable? Commented Dec 9, 2022 at 20:57

2 Answers 2

2

The controller methods you are after are those on the standard controller that your custom controller is given via its constructor. You need to make sure your code can access those methods for you to call. Just because your custom controller is called a controller doesn't mean it is the same thing as the standard controller; they are two distinct objects.

In Object Orientation this is the difference between inheritance ("is a") and aggregation ("has a"). Take this analogy: a Ford Kuga is a Car but the Ford Kuga has a Driver. You might construct a class for FordKuga that extends the class Car and give it a constructor that accepts a Driver class object. In your case you are effectively attributing properties of the Driver to the Car, but really you should not ask the Car what colour its eyes are (myCar.eyeColour() is not going to work), and instead ask what colour the Car's Driver's eyes are (myCar.driver.eyeColour() does work).

Anyway, back to your problem. If you only need the standard controller methods to be accessible in your unit test and nowhere else (not even in other methods on your custom controller) you could resolve this by making sure your unit test keeps a reference to the standard controller and use that wherever you need to call one of these standard controller methods:

    @isTest public static void TestMyNewCaseListController(){
        ...
        ApexPages.StandardSetController standardController = new ApexPages.StandardSetController(Cases);

        MyNewCaseListController controller  = new MyNewCaseListController(standardController);

        string filter = ApexPages.currentPage().getParameters().get('filterId');
        standardController.setPageSize(50);
        ...

Clearly, you need to update each call to a standard controller method in your unit test to use the standardController variable.

On the other hand, if you find your custom controller actually needs to use the standard controller in other methods you can have that custom controller keep hold of the standard controller in an attribute or property like this:

public with sharing class MyNewCaseListController {
    /**
     * Provide access to the standard controller using a property with public
     * getter. This means other classes (including unit tests) can access it.
     */
    public ApexPages.StandardSetController ctrl { public get; private set; }

    /**
     * Initialize the new instance using the given parameters.
     *
     * @param ctrl the standard controller. Must not be null.
     */
    public MyNewCaseListController(ApexPages.StandardSetController ctrl) {
        // Save the standard controller in a property for later access
        this.ctrl = ctrl;

        ...

At this point your unit test can now access your standard controller, e.g.:

        insert Cases;
        MyNewCaseListController controller  = new MyNewCaseListController(new ApexPages.StandardSetController(Cases));

      
        
        string filter = ApexPages.currentPage().getParameters().get('filterId');

        // Need to set the page size on the standard controller that the
        // custom controller is using
        controller.ctrl.setPageSize(50);

Of course, the custom controller can also now access this standard controller in any (non-static) method by simply referring to the "ctrl" property.

As noted in comments, it looks like you need a bit of a crash course in OOP and Apex, but this might get you on your way with the immediate problem you have.

1
  • Thanks @Phil W! Yeah I am trying to learn on the fly. But I think I get it now. At least the code now works. Commented Dec 12, 2022 at 22:21
1

Following up on the comment above, the "constructor parameter" is the 'New ApexPages.StandardSetController()'. From your method definition, this is stored in the ctrl attribute of your controller extension.

So, in method, you would need to store the standardsetcontroller in an attribute then reference it in the test --> controller.[storedStandardSetControllerAttribute].setPageSize(50);

3
  • @ Tony Kirumba thanks for the help. Maybe I am just too for this and need to start slower. But I just can't figure out the syntax for storing the standardsetcontroller in an attribute. I get what you are saying about how in the class ctrl is used as the attribute when the controller is instantiated. I just have now idea how to do that for when I create the new controller. If you or @PhilW have any resources where I can better understand this I would appreciate it. Commented Dec 9, 2022 at 22:58
  • Do some research on blogs about controller extensions and focus on the ones that have tests, that should help build your foundation. Meanwhile to resolve this specific problem, the answer by @Phil W is exactly what you need Commented Dec 12, 2022 at 13:41
  • Thanks Tony. Slowly bit by bit, learning. But thanks to people like you and Phil and @ TheArchitecta Commented Dec 12, 2022 at 22:23

You must log in to answer this question.

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