function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Adam LeeAdam Lee 

Help on Test Class for VF Controller

Hi all,

We're quite new to Apex.

we're trying to get a test class for a controller but only covered 40% code coverage.

We cannot get our head round to achieve 100%

Hope you can help

This is the Controller. The 2 parts aren't covered are Task and Hist
public with Sharing class DQMBulkUpdate{
    
    private final Account Account;
   
    public Account getAccount() {
        return Account;
    }
    public DQM_History__c DQMHistory {get; set;}
    
    public DQM_History__c getDQMHistory() {
        return DQMHistory;
    }
    
  /*  public void setDQMHistory(DQM_History__c DQMHistory) {
        this.DQMHistory = DQMHistory;
    }*/
    public List<wrapReview> wrapReviewList {get; set;}
    public List<wrapReview> getwrapReviewList() {
        return wrapReviewList;
    }
    
    public List<DQM_Review__c> selectedReviews{get;set;}
    public List<DQM_Review__c> getDQMReview() {
        return selectedReviews;
    }
   
    public DQMBulkUpdate(){
        Account = [SELECT Id, Name, BillingPostalCode, FRN__c FROM Account 
                   WHERE Id = :ApexPages.currentPage().getParameters().get('id')];
        DQMHistory = new DQM_History__c();    
        if(wrapReviewList == null) {
            wrapReviewList = new List<wrapReview>();
            
            for(DQM_Review__c a: [SELECT Id
                                  , Name
                                  , Agency_Number__c
                                  , Agency_Number__r.Primary_Contact__c
                                  , Agency_Number__r.Agency_Name__c
                                  , Type__c
                                  , Trigger_Target_Value__c
                                  , Triggered_Date__c
                                  , Triggered_Metric_Value__c
                                  , Owner_Name__c
                                  , Status__c
                                  , CreatedDate
                                  , Account_Id__c
                                  , Account__c
                                  , Generated_From__c
                                  FROM DQM_Review__c
                                  WHERE Status__c = 'Open' And
                                  Account_Id__c = :ApexPages.currentPage().getParameters().get('id')]) 
            {
				wrapReviewList.add(new wrapReview(a));                
			}
        }
    }
    
    public PageReference Save(){
        List<DQM_History__c> history = new List<DQM_History__c>();
  		
        If (DQMHistory.Generate_Task__c == true) {
                Task task = new Task ();   
                task.WhatId = ApexPages.currentPage().getParameters().get('id');
                //task.WhoId = DQMHistory.Contact_Reviewed_With__c;
                task.ActivityDate = DQMHistory.Review_Date__c;
                task.Duration_Mins__c = 10;                    
                task.Status = 'Completed';
                task.OwnerId = Userinfo.getUserId();                      
                task.Priority = 'Normal';   
                task.Subject = 'DQM Review';                  
                task.IsReminderSet = false;
                task.Completed_Date__c = DQMHistory.Review_Date__c;
                task.IP_Category__c = 'S Q & R Research';
                task.Description = DQMHistory.Comments__c; 
                If (DQMHistory.Contact_Type__c == 'Telephone'){
                    task.Type = 'Outbound Call';
                } else if (DQMHistory.Contact_Type__c == 'Face to Face') {
                    task.Type = 'Meeting';
                } else if (DQMHistory.Contact_Type__c == 'Email') {
                    task.Type = 'Email';
                } else {
                    task.Type = 'Note'; 
                } 
            	insert task;
        }
        
        for(DQM_Review__c addrev : selectedReviews)
        {
            DQM_History__c hist = new DQM_History__c ();
            hist.RecordTypeId = Schema.SObjectType.DQM_History__c.getRecordTypeInfosByName().get('Salesforce DQM History').getRecordTypeId();                     
            hist.Review_Date__c = DQMHistory.Review_Date__c;
            hist.Due_Date__c = DQMHistory.Due_Date__c ;   
            hist.Outcome__c = DQMHistory.Outcome__c;
            hist.Comments__c = DQMHistory.Comments__c;
            hist.Contact_Type__c = DQMHistory.Contact_Type__c;     
            hist.Review__c = addrev.id;
            hist.Generate_Task__c = false;
            history.add(hist);  
        }

        insert history; 

        PageReference acctPage = new PageReference('/' + ApexPages.currentPage().getParameters().get('id'));
        acctPage.setRedirect(false);
        return acctPage;
    }

    public void processSelected() {
        selectedReviews = new List<DQM_Review__c>();
        
        for(wrapReview wrapReviewObj : wrapReviewList) {
            if(wrapReviewObj.selected == true) {
                selectedReviews.add(wrapReviewObj.rev);
            }
        }
    }
    
    // This is our wrapper/container class. In this example a wrapper class contains both the standard salesforce object Account and a Boolean value
    public class wrapReview {
        public DQM_Review__c rev {get; set;}
        public Boolean selected {get; set;}
        
        public wrapReview(DQM_Review__c r) {
            rev = r;
            selected = false;
        }
    }
    
  //  public ApexPages.StandardController myDQMHistoryController {get; set;}
  //  public DQM_History__c DQMHistory {get; set;}
    
}
Here's the test class so far
 
@istest
public class TestDQMBulkUpdate {
    static testMethod void TestDQMBulkUpdateController(){
        
        String txt = 'TESTING123';
        
        //List active User
        List<User> Owner = [Select Id from User where IsActive = true LIMIT 1];
                
        //Insert new Account
        Account acc = new Account(Name='TESTACCOUNT', OwnerId = Owner[0].Id); 
        upsert(acc);

           
     Test.startTest();           
        PageReference pageRef = new PageReference('/apex/DQMBulkUpdate?id=' + acc.Id);
        Test.setCurrentPage(pageRef);
		
	    DQMBulkUpdate controller = new DQMBulkUpdate();

     // ApexPages.currentPage().getParameters().put('Account',acc.Id);	
        
        controller = new DQMBulkUpdate(); 
        controller.getAccount();
        controller.processSelected();
        controller.getDQMHistory();
        controller.getDQMReview();
        controller.getwrapReviewList();
       	controller.Save();
         
 
        String nextPage = controller.Save().geturl();
        System.assertEquals('/' + acc.id, nextPage);

        Boolean error = ApexPages.hasMessages();
        System.assertequals(false,error);
        
       // system.debug(rlist[0].id);  
        
    }
      
}

Thanks in advance for your help
 
Best Answer chosen by Adam Lee
James LoghryJames Loghry
Hi Adam,

I'm not sure if I was clear about this earlier, but your test class behaves the same as if you executed the code manually.  That is, if you execute code and come across a logical block like a for loop or if/else statement, it will only execute that block if the criteria are met.  In the first case, it was a simple criteria that we needed to set.

For the case of the for loop, the loop will not run if selectedReviews is empty. So that being said, you'll need to populate the selectedReviews list prior to when you call the save method.

Looking further into your code it looks like selectedReviews is supposed to be populated via the "processSelected" method which you are calling.  However, it looks like this is also dependent on the DQM_Review SOQL query in your constructor.  This means you'll need to create mock data for your DQM_Review object.  The DQM_Reviews will need to have a Status__c = 'Open' and Account_ID__c = the account that you create in your unit test.

Hope that helps.

All Answers

James LoghryJames Loghry

Most tools like the developer console or MavensMate or the Fore.com IDE have a code coverage highlight after you run your unit test.  After running your test, open the the test result or your controller and you should see the missing 60% code coverage.  From there, it's a matter of determining why your code is not covered, and what data in your test class you need to change in order to cover the code.  

From what I'm reading in your code, it looks like simply setting 
 

controller.DQMHistory.Generate_Task__c = true;
At line 29 before you call your save method should get you a bit more code coverage. 

Also keep in mind that you should be testing all the logic in your controller, so you will likely need additional test cases to test exception cases, boundary conditions, etc.
Adam LeeAdam Lee
Cannot believe its just one line missing. 67% coverage now. Just got the “hist.” section to cover now Thanks so much
Adam LeeAdam Lee
Any ideas how I can cover this code in he test?
for(DQM_Review__c addrev : selectedReviews)
        {
            DQM_History__c hist = new DQM_History__c ();
            hist.RecordTypeId = Schema.SObjectType.DQM_History__c.getRecordTypeInfosByName().get('Salesforce DQM History').getRecordTypeId();                     
            hist.Review_Date__c = DQMHistory.Review_Date__c;
            hist.Due_Date__c = DQMHistory.Due_Date__c ;   
            hist.Outcome__c = DQMHistory.Outcome__c;
            hist.Comments__c = DQMHistory.Comments__c;
            hist.Contact_Type__c = DQMHistory.Contact_Type__c;     
            hist.Review__c = addrev.id;
            hist.Generate_Task__c = false;
            history.add(hist);  
        }


 
James LoghryJames Loghry
Hi Adam,

I'm not sure if I was clear about this earlier, but your test class behaves the same as if you executed the code manually.  That is, if you execute code and come across a logical block like a for loop or if/else statement, it will only execute that block if the criteria are met.  In the first case, it was a simple criteria that we needed to set.

For the case of the for loop, the loop will not run if selectedReviews is empty. So that being said, you'll need to populate the selectedReviews list prior to when you call the save method.

Looking further into your code it looks like selectedReviews is supposed to be populated via the "processSelected" method which you are calling.  However, it looks like this is also dependent on the DQM_Review SOQL query in your constructor.  This means you'll need to create mock data for your DQM_Review object.  The DQM_Reviews will need to have a Status__c = 'Open' and Account_ID__c = the account that you create in your unit test.

Hope that helps.
This was selected as the best answer
Adam LeeAdam Lee
@James 

you've been a great help last time.

Would you any chance have any ideas how I can do this?

https://developer.salesforce.com/forums/#!/feedtype=SINGLE_QUESTION_DETAIL&dc=Visualforce_Development&criteria=OPENQUESTIONS&id=906F0000000BNmkIAG (https://developer.salesforce.com/forums/#!/feedtype=SINGLE_QUESTION_DETAIL&dc=Visualforce_Development&criteria=OPENQUESTIONS&id=906F0000000BNmkIAG)

Thanks

Adam,