-4

Now it works :) Thank you guys!

public class VFController {
    public VFController(ApexPages.StandardSetController setCon){}

    public ApexPages.StandardSetController setCon {
        get {
            if(setCon == null) {
                setCon = new ApexPages.StandardSetController(Database.getQueryLocator(
                    [SELECT Id, Title__c FROM Tool__c]));
            }
            String listViewUrl = ApexPages.currentPage().getParameters().get('vfRetURLInSFX');
            String listViewId = listViewUrl.substringAfter('filterName=');
            setCon.setPageSize(2000);
            setCon.setFilterId(listViewId);
            return setCon;
        }
        set;
    }

    public List<Tool__c> getTools() {
        return (List<Tool__c>) setCon.getRecords();
    }
}

And my Test:

Tool__c tool = new Tool__c(
        Name = 'Test',
        Title__c = 'Title'
    );
    insert tool;

    List<Tool__c> tools = [SELECT Id, Title__c FROM Tool__c];

    Test.startTest();  
        Test.setCurrentPage(Page.VfPage);        
        ApexPages.StandardSetController setCon = new ApexPages.StandardSetController(Database.getQueryLocator(
                [SELECT Id, Title__c FROM Tool__c]));

        ApexPages.currentPage().getParameters().put('vfRetURLInSFX', 'filterName=00V9w000000mqREARY');
        setCon.setPageSize(2000);
        VFController controller = new VFController(standardSetController);
    Test.stopTest();

controller.getTools();
System.assertEquals('Test', controller.getTools()[0].Name);

2 Answers 2

0

The difference between testing a VF and a trigger is that you need to simulate all the users interactions, so if your user is supposed to click a button to make the page work, you need to call that method in your test.

In you case, you just need to call the getTools method, so something like:

System.assertEquals('Test', controller.getTools()[0].Name)

should solve your problem

2
  • Thank you. Now I have 75% test coverage. But I also get now an error: System.NullPointerException: Attempt to de-reference a null object. There are still 3 lines without coverage: setCon.setPageSize(2000); setCon.setFilterId(listViewId); return setCon; So I think my List doesn't get setCon, because return setCon; is without coverage. I really don't know how to test it :(
    – Apelsinova
    Jul 26, 2019 at 11:03
  • No, it means you got an error on the last line that was covered. In this case listViewUrl.substringAfter('filterName='). You need to set that parameter in your test class. Something like `PageReference testPage = Page.VfPage; testPage.getParameters().put('vfRetURLInSFX', 'filename=idOFtheListView'); Jul 26, 2019 at 13:09
2

The golden rule of unit testing is You only gain coverage for lines of code that are executed as part of a test method.

In a unit test, you're generally responsible for ensuring that you provide all of the data that your class needs so that it can run. This usually takes the form of creating and inserting SObjects before running your test proper (as you do with your Tool__c tool = new Tool__c(...).

The other thing you need to worry about, specifically for Visualforce controllers (and controller extensions) are the query string parameters of the URL. vfRetURLInSFX isn't going to be magically set for you, you need to provide that information too. You can do this by using ApexPages.currentPage().getParameters().

The getParameters() method returns a Map<String, String>. The key of the map is the query string parameter name (i.e. vfRetURLInSFX).

Now that that has been said, we can get to the most important part of unit testing. While the goal is to get at least 75% coverage, the real value of unit tests comes from the assertions that you make. 100% coverage is nice, but it's not the end of the story (and sometimes 100% coverage is impossible to attain). Assertions are used to verify that your code behaves in the way you expect it to behave. If you have an add(Integer op1, Integer op2) method, and add(2, 2) returns 5, "fish", or anything other than exactly 4, you know you have a problem. Assertions help alert you to problems like this.

If you make a change to a record via DML (insert, update, delete, undelete), or change the "state" of a class (set/alter a class variable), chances are that you should have an assertion to verify that you made the correct change.

You also want to be writing tests that cover many different scenarios, not just the "happy path" where your input is well-formed and exactly what you expect it to be. What happens if the vfRetURLInSFX parameter is null? What happens if you don't have any Tool__c records? What happens if you pass in a standardSetController for a different object?

The idea here is that the more situations you test for, the more robust the code being tested will be. Also, by testing a sufficient number of scenarios, your coverage will naturally rise to a higher and higher level.

You must log in to answer this question.

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