You need to sign in to do that
Don't have an account?
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;
}
}
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
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 */
}
}
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.
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.
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);
}
}
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.