1

I am trying to write a test class for a Visualforce page, which returns a list of associated records to the contact object. The test class is throwing no errors, however is also not covering the Extension either.

I have an understanding that I have to create test data in the Test class, then call the standard controller, and then run an instance of the extension.

EDIT: this was failing due to a trigger on the same object. Note to self - CHECK TEST RESULTS outside of developer console!!

Thanks in advance!

VF:

<apex:page showHeader="false" standardStylesheets="false" standardController="contact" extensions="studentResultsExtension">

<div class="cell">
<button class="btn btn-default pull-right" onclick="selectElementContents(document.getElementById('courseEnrollments') );">
<span class="glyphicon glyphicon-copy"/>&nbsp;&nbsp;Copy Table</button>
<h1>Course Enrollment Information</h1>

<table id="courseEnrollments" class="table table-striped" style="width:100%;">
<thead class="tableHeadBlue">
    <tr>
        <td>Qualification</td>
        <td>End Date</td>
        <td>Unit Code</td>
        <td>Unit Name</td>
        <td>Result</td>
        <td>Grade</td>
        <td>Trainer</td>
    </tr>
</thead>
<tbody>
    <apex:repeat value="{!couEnr}" var="ce">
    <tr>
        <td>{!ce.Qualification__c}</td>
        <td><apex:outputText value="{0, date, MMMM d','  yyyy}"><apex:param value="{!ce.Course_End_Date__c}" /></apex:outputText></td>
        <td>{!ce.Unit_Code__c}</td>
        <td>{!ce.Unit_Description__c}</td>
        <td>{!ce.Total_Grade_Result__c}</td>
        <td>{!ce.Total_Weighted_Grade__c}</td>
        <td>{!ce.Course_Trainer__c}</td>
    </tr>
    </apex:repeat>
</tbody>
</table>
</div>
</apex:page>

APEX Extension:

public with sharing class studentResultsExtension {

public list <Course_Enrollment__c> couEnr {get;set;}
public ID contactID {get;set;}

public studentResultsExtension(ApexPages.StandardController controller) {

    contactID = ApexPages.currentPage().getParameters().get('Id');

    couEnr = [SELECT id,name,Course_End_Date__c,Course_Trainer__c,Qualification__c,Survey_ID__c,Total_Grade_Result__c,Total_Weighted_Grade__c,Unit_Code__c,Unit_Description__c FROM course_enrollment__c WHERE contact__c = :contactID];
}
}

Test Class

@istest
public class testStudentResultsExtension {
public static testMethod void TestStudentResults(){

    test.startTest();
    Id ceRecordType = [Select Id, Name from RecordType where name = 'Higher Education' limit 1].Id;

    Account testAccount = new Account();
    testAccount.Name='Test Company Name123';
    insert testAccount;

    Contact testContact = new Contact();
    testContact.firstname='test';
    testContact.lastname='contact';
    testContact.account=testAccount;
    insert testContact;

    Course_enrollment__c testCourseEnrollment = new Course_Enrollment__c();
    testCourseEnrollment.RecordTypeId=ceRecordType;
    testCourseEnrollment.contact__r.id=testContact.Id;
    insert testCourseEnrollment;

    PageReference pageRef = Page.studentResults;
    Test.setCurrentPage(pageRef);

    pageRef.getParameters().put('id', String.valueOf(testContact.Id));
    ApexPages.StandardController sc = new ApexPages.StandardController(testContact);
    studentResultsExtension viewEnrollments = new studentResultsExtension(sc);

    system.assert(sc != null);

    List<Course_enrollment__c> couEnr  = new List<Course_Enrollment__c>{};
        couEnr = [SELECT id,name FROM Course_Enrollment__c WHERE Contact__r.id = :testContact.Id];

    test.stopTest();
}
}
3
  • 1
    Hey just so you know, if you select an entire code/markup block and hit CTRL + K, it will indent for you. Or hit the {} button in the rich text editor.
    – Adrian Larson
    May 10, 2017 at 1:09
  • @TheMikeyBoosh - Is this code exactly as it is in your org or is it abbreviated. Maybe its just cause it is late and i am missing something but if no errors are thrown this should cover something....How are you checking coverage?
    – Eric
    May 10, 2017 at 1:39
  • @Eric Thanks for your input, please see the answer comment. May 11, 2017 at 1:13

2 Answers 2

2

You have a number of minor problems with your code. I'm not sure why you didn't see any errors, but I would expect your code to crash with a System.NullPointerException or perhaps a DmlException if Contact__c is required:

testCourseEnrollment.contact__r.id=testContact.Id;

Contact__r here is null, so you're not actually assigning that contact to the record. Instead, use the normal Contact__c notation:

testCourseEnrollment.Contact__c=testContact.Id;

As a matter of practicality, if you're ever using __r.Id, you're probably doing something wrong.

Also, I'd recommend not using getParameters when you're using a StandardController. The following code is equally effective:

public with sharing class studentResultsExtension {

public list <Course_Enrollment__c> couEnr {get;set;}
public ID contactID {get;set;}

    public studentResultsExtension(ApexPages.StandardController controller) {
        contactID = controller.getId();
        couEnr = [SELECT id,name,Course_End_Date__c,Course_Trainer__c,Qualification__c,Survey_ID__c,Total_Grade_Result__c,Total_Weighted_Grade__c,Unit_Code__c,Unit_Description__c FROM course_enrollment__c WHERE contact__c = :contactID];
    }
}

Again, even if the parameter were null, you should still automatically get 100% coverage.

I should also mention that, while not super-critical, there's no point in testing basic system functionality:

system.assert(sc != null);

It is literally impossible to reach this line of code and have sc be null. It can't happen.

Similarly:

    couEnr = [SELECT id,name FROM Course_Enrollment__c WHERE Contact__r.id = :testContact.Id];

Isn't testing your extension, it's testing the ability of the system to execute a query (and there's that __r.Id again).

Also, this query is problematic:

Id ceRecordType = [Select Id, Name from RecordType where name = 'Higher Education' limit 1].Id;

If someone later creates another record type on another object with the same name, you might get the wrong one. Use the following instead:

Id ceRecordType = Course_Enrollment__c.SObjectType.getDescribe()
    .getRecordTypeInfosByName().get('Higher Education').getRecordTypeId();

To properly test your controller, make sure that:

System.assertEquals(1, viewEnrollments.couEnr.size());

Finally, it could just be that you can't see the coverage for some reason. Perhaps the code coverage didn't update correctly. Try going to Setup > Develop > Test Execution, and clear your code coverage first, and then run your test.

1
  • Hey sfdcfox... I am selecting this as the correct answer to help with anyone writing test classes, however, the test was failing due to a seemingly unrelated (related!) trigger on the same object. Still, thanks for the help with the class, I suspect it would have failed with the syntax errors alone! May 11, 2017 at 1:15
2

The main issue is could be this line: testContact.account=testAccount; where you are inserting contact. Here contact will not be associated with the Account. You have to assign AccountId instead of Account object.

Correct code will be as follows:

Contact testContact = new Contact();
testContact.firstname='test';
testContact.lastname='contact';
testContact.accountId=testAccount.id;
insert testContact;

and 2nd issue will be testCourseEnrollment.contact__r.id=testContact.Id;

it should be testCourseEnrollment.contact__c = testContact.Id;

finally, I do not find the reason of putting test.startTest(); at the beginning of the method and test.stopTest(); at the end of the method.

You must log in to answer this question.

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