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
jtresjtres 

Cannot figure out how to write a proper test class

Here is the situation which I find myself in.  My group has setup and object which will accept input via an email service which we have created.  From this object I want to create three contacts and two relationships.  My trigger is as follows, but I have been unable to create a test class that will get more than 0% coverage.  I'm starting to go crazy so I'm hoping someone will be able to point me in the right direction.

 

trigger parseStudentApplication on Student_Application__c (after insert) {

for (Student_Application__c sa : Trigger.new) {

Contact student = new Contact();

Contact father = new Contact();

Contact mother = new Contact();

npe4__Relationship__c studentToFather = new npe4__Relationship__c();

npe4__Relationship__c studentToMother = new npe4__Relationship__c();

student.FirstName = sa.Student_First_Name__c;

student.LastName = sa.Student_Last_Name__c;

student.MailingStreet = sa.Student_Address__c;

student.MailingCity = sa.Student_City__c;

student.MailingState = sa.Student_State__c;

student.MailingPostalCode = sa.Student_Zip__c;

student.Email = sa.Student_Email_Address__c;

student.Phone = sa.Student_Phone__c;

student.Birthdate = sa.Student_Date_of_Birth__c;

father.FirstName = sa.Father_First_Name__c;

father.LastName = sa.Father_Last_Name__c;

if(sa.Father_Address__c == null){

father.MailingStreet = sa.Student_Address__c;

father.MailingCity = sa.Student_City__c;

father.MailingState = sa.Student_State__c;

father.MailingPostalCode = sa.Student_Zip__c;

}

else{

father.MailingStreet = sa.Father_Address__c;

father.MailingCity = sa.Father_City_Text__c;

father.MailingState = sa.Father_State_Text__c;

father.MailingPostalCode = sa.Father_Zip__c;

}

 

if(sa.Mother_Address__c == null){

mother.MailingStreet = sa.Student_Address__c;

mother.MailingCity = sa.Student_City__c;

mother.MailingState = sa.Student_State__c;

mother.MailingPostalCode = sa.Student_Zip__c;

}

else{

mother.MailingStreet = sa.Mother_Address__c;

mother.MailingCity = sa.Mother_City__c;

mother.MailingState = sa.Mother_State__c;

mother.MailingPostalCode = sa.Mother_Zip__c;

}

studentToFather.npe4__Contact__c = student.Id;

studentToFather.npe4__RelatedContact__c = father.Id;

studentToFather.npe4__Description__c = 'Father';

studentToMother.npe4__Contact__c = student.Id;

studentToMother.npe4__RelatedContact__c = mother.Id;

studentToMother.npe4__Description__c = 'Mother';

insert student;

insert father;

insert mother;

insert studentToFather;

insert studentToMother;

}

} 

Best Answer chosen by Admin (Salesforce Developers) 
ccMarkccMark

Have you tried creating a test class with something like the following?

 

@isTest

private class parseStudentApplicationTest {

static testMethod void myUnitTest() {Student_Application__c sa =

new Student_Application__c();

sa.Student_First_Name__c = 'testFirstName';sa.Student_Last_Name__c =

'testLastName';

sa.Student_Address__c = '989 test street';sa.Student_City__c =

'TestCity';

sa.Student_State__c = 'TestSate';sa.Student_Zip__c =

'99999';

sa.Student_Email_Address__c = 'test@test.com';sa.Student_Phone__c =

'9995551212';

sa.Student_Date_of_Birth__c = '01/01/2000';sa.Father_First_Name__c =

'testFatherFirstName';

sa.Father_Last_Name__c = 'testFatherLastName';sa.Father_Address__c =

'TestFatherAddress'; insert sa;

 

/* You'll want to change and insert additional Student Applicant data with however many different

data sets you need to insure you get 100% test code coverage */

}

}

 

 

All Answers

ccMarkccMark

Have you tried creating a test class with something like the following?

 

@isTest

private class parseStudentApplicationTest {

static testMethod void myUnitTest() {Student_Application__c sa =

new Student_Application__c();

sa.Student_First_Name__c = 'testFirstName';sa.Student_Last_Name__c =

'testLastName';

sa.Student_Address__c = '989 test street';sa.Student_City__c =

'TestCity';

sa.Student_State__c = 'TestSate';sa.Student_Zip__c =

'99999';

sa.Student_Email_Address__c = 'test@test.com';sa.Student_Phone__c =

'9995551212';

sa.Student_Date_of_Birth__c = '01/01/2000';sa.Father_First_Name__c =

'testFatherFirstName';

sa.Father_Last_Name__c = 'testFatherLastName';sa.Father_Address__c =

'TestFatherAddress'; insert sa;

 

/* You'll want to change and insert additional Student Applicant data with however many different

data sets you need to insure you get 100% test code coverage */

}

}

 

 

This was selected as the best answer
jtresjtres
I've tried doing something similar to this before, but every time I save the trigger it still says I have 0% coverage and won't save the trigger to the server.
ccMarkccMark

Did you save the test class for the trigger on the server before you saved the trigger?

 

When you post your code, it's going to try to run test code coverage and if your test class isn't available you'll get 0% coverage.

ShikibuShikibu

On your sandbox or developer org, save the trigger and the test class. Then do "run tests" for the test class. It will give you coverage statistics. You can click on the coverage statistics and a popup will appear, showing the source each line of all code that had any coverage, displayed in color indicating whether the code was executed or not.

 

Also, you may find it helpful to separate your logic from your trigger -- make the trigger very simple,  just passes data to a class. Put the processing logic into the class. Then you can test the logic and the activation of the trigger separately.

 

Also, your trigger performs five inserts for each record in the trigger data set. You are likely to encounter problems with governor limits. This can happen, for instance, when data is inserted from the data loader or via the API.

jtresjtres

Ok, I've rewritten the trigger so that the logic is separated from the trigger itself.  And on my test class I am getting coverage now, but I keep getting an error relating to an insert statement claiming I don't have a required field set.  I've looked over the objects where this error continues to appear but have not been able to find what is causing an issue.  Also I am not sure if the trigger is written correctly to pass all the newly created objects to the class which does the actual parsing.

 

Trigger

trigger parseStudentApplication on Student_Application__c (after insert) {

    List<Student_Application__c> studentApps = Trigger.new;

    {

StudentApplicationParser sap = new StudentApplicationParser();

sap.Parse(studentApps);

    } 

    

}

 

 

Class which does the work

public with sharing class StudentApplicationParser {

public void Parse(List<Student_Application__c> sas)

{

List<Contact> contacts = new List<Contact>();

List<npe4__Relationship__c> relationships = new List<npe4__Relationship__c>();

List<Involvement__c> involvements = new List<Involvement__c>();

for(Student_Application__c sa : sas)

{

Contact student = new Contact();

Contact mother = new Contact();

Contact father = new Contact();

npe4__Relationship__c relToMother = new npe4__Relationship__c();

npe4__Relationship__c relToFather = new npe4__Relationship__c();

Involvement__c studentInvolvement = new Involvement__c();

student.FirstName = sa.First_Name__c;

student.LastName = sa.Last_Name__c;

mother.FirstName = sa.Mother_First_Name__c;

mother.LastName = sa.Mother_Last_Name__c;

father.FirstName = sa.Father_First_Name__c;

father.LastName = sa.Father_Last_Name__c;

relToMother.npe4__Contact__c = student.Id;

relToMother.npe4__RelatedContact__c = mother.Id;

relToMother.npe4__Description__c = 'Mother of ' + student.FirstName + ' ' + student.LastName;

relToMother.npe4__Status__c = 'Current';

relToFather.npe4__Contact__c = student.Id;

relToFather.npe4__RelatedContact__c = father.Id;

relToFather.npe4__Description__c = 'Father of ' + student.FirstName + ' ' + student.LastName;

relToFather.npe4__Status__c = 'Current';

studentInvolvement.Contact__c = student.Id;

studentInvolvement.Involvement_Level__c = 'Student';

contacts.add(student);

contacts.add(mother);

contacts.add(father);

relationships.add(relToMother);

relationships.add(relToFather);

involvements.add(studentInvolvement);

}

 

insert relationships;//errors occur here

insert involvements;

insert contacts;

}

} 

 

Test Class

@isTest

private class TestParseStudentAppTrigger {

 

    static testMethod void myUnitTest() {

        Student_Application__c sa = new Student_Application__c();

        sa.First_Name__c = 'StudentFirstName';

        sa.Last_Name__c = 'StudentLastName';

        sa.Father_First_Name__c = 'FatherFirstName';

        sa.Father_Last_Name__c = 'FatherLastName';

        sa.Mother_First_Name__c = 'MotherFirstName';

        sa.Mother_Last_Name__c = 'MotherLastName';

        

        User u1 = [Select id from User where alias='JTres'];

        

        System.runAs(u1){

        

            insert sa;

        }   

        

        Contact student = [Select c.LastName, c.FirstName From Contact c Where c.FirstName = 'StudentFirstName'];

        Contact father = [Select c.LastName, c.FirstName From Contact c Where c.FirstName = 'FatherFirstName'];

        Contact mother = [Select c.LastName, c.FirstName From Contact c Where c.FirstName = 'MotherFirstName'];

        

        System.assertNotEquals(student, null);

        System.assertNotEquals(father, null);

        System.assertNotEquals(mother, null);

    }

} 

ccMarkccMark

Nice! Keep in mind that even in test methods the field requirements are enforced as well as validation rules, etc.  So, it's important to take that into account when adding data manually in the test class.  Were you able to identify which field the insert is missing?  If so, just be sure to add a line for it similar to what you did with the sa.Mother_Last_Name__c = 'MotherLastName'; lines. 

 

Keep in mind that you may have a lookup field required.  For instance the Account lookup field may be required on opportunity.  If this is the case, you'd need to insert an account record first, then set the lookup field before you save the opportunity.