1

I'm a total newb when it comes to salesforce and have been learning it for a couple of weeks now.

So I've been plugging away at a few triggers and I've got them working in my sandbox. Now I'm writing test classes for them so I can deploy them to my organization. I need some help in understanding how test classes work. I've read the workbooks and a ton of blogs and other questions and I think I have the basic idea down but there's just something that's not connecting for me. Anyway let me explain my code and hopefully someone can see what I'm missing.

So first here's my trigger:

trigger updatePrMEnCCeO on Programs__c (after update) {

//Create List of old program objects
List<Programs__c> prOld = trigger.old;

//Create List of Apps that need changing
List<Application__c> app = [SELECT Program_Manager__c, Enrollment_Counselor__c, Center_Owner__c, Id from Application__c WHERE Programs__c=:prOld[0].id];


//loop through all edited programs__c object
for (Programs__c edited : trigger.new) {


    //checks for a difference in any of the three fields and then changes all three (possibly faster if inner logic placed into a switch or nested if)
    if ((prOld[0].program_manager_lookup__c != edited.program_manager__c) || (prOld[0].Enrollment_Counselor__c != edited.Enrollment_Counselor__c) ||(prOld[0].Center_Owner__c != edited.Center_Owner__c) ) {
         for (Integer i=0; i<app.size(); i++) {
            app[i].Program_Manager__c=edited.Program_Manager_lookup__c;
            app[i].Enrollment_Counselor__c=edited.Enrollment_Counselor__c;
            app[i].Center_Owner__c=edited.Center_Owner__c;
            update app[i];
         }
    }
}

 }

I'm sure you can tell, but what it does is look for any of 3 fields that were changed in the program and then updates all the associated applications with the new values of the fields

And here's my test class:

@isTest(SeeAllData=true)
public with sharing class updatePrMEnCCeOTest {
public static testMethod void updatePrMEnCCeOTest () {
//Begin test
test.starttest();

//New Program
Programs__c Prog = new Programs__c();
prog.Centers_LOOKUP__c='a0wJ0000003x3PIIAY';
prog.start_date__c=date.parse('08/01/2014');

//New Application
Application__c App = new Application__c();
app.Contact__c='003J000000t6Z6bIAE';

//Inserts
insert prog;    
insert app;

//set Program values
prog.program_manager_lookup__c='005d0000002xQjZ';
prog.enrollment_counselor__c='005d0000002xQjZ';
prog.center_owner__c='005d0000002xQjZ';

//update Program and set off trigger
update prog;

//check for expected outcome
System.assertEquals('005d0000002xQjZ',app.program_manager_lookup__c);
System.assertEquals('005d0000002xQjZ',app.enrollment_counselor__c);
System.assertEquals('005d0000002xQjZ',app.center_owner__c);

//end test
test.stoptest();
}
 }

As I'm understanding test classes, you basically just need to create an instance of the objects that you're working with in your trigger, and then do something that causes the trigger to fire, here, I'm creating Programs and Applications (The hard coded values are because of the multitude of errors I got without them, they're seemingly required).

I'm finally getting 100% code coverage, but the test is failing with this error: system.dmlexception:insert failed. First exception on row0; first error: INVALID_CROSS_REFERENCE_KEY, invalid cross reference id:[]

Now I know I can hardcode an ID in, but apart from that being against best practices (as I understand them outlined in the workbooks/blogs), it still won't matter because when I try to deploy to the server, I get completely different errors and my trigger gets 0% code coverage.

I'm trying to deploy via eclipse with the force.com ide plugin.

thanks for any help and explanations, and I apologize if I'm not explaining it properly, I'm sort of lost here, and really just something isn't connecting for me conceptually about how testing works :)

1 Answer 1

1

When you hard code Id values in test classes, it will be worked for that sandbox, but since that particular Id will not exists in other sandboxes or Production your test cases will be failed there and have to face the code coverage issue.
First you should create your test data at the start of your test class(Centers_LOOKUP_c object, Contact_c, etc. ). Below is a untested sample for your test classs

@isTest(SeeAllData=true)
public with sharing class updatePrMEnCCeOTest {
public static testMethod void updatePrMEnCCeOTest () {

//Creating hepler test data
Centers_LOOKUP__c center = new Centers_LOOKUP__c();
center.Name = 'Center Name';
insert center;

Contact__c con = new Contact__c();
con.Name = 'Contact Name';
insert con;

Program_Manager_Lookup__c pmLookup = new Program_Manager_Lookup__c();
pmLookup.Name = 'Program Manager Lookup';
insert pmLookup;

Enrollment_Counselor__c eCounselr = new Enrollment_Counselor__c();
eCounseler.Name = 'Counseler';
insert eCounseler;

Center_Owner__c cOwner = new Center_Owner__c();
cOwner.Name = 'Center Owner';
insert cOwner;

//Begin test
test.starttest();

//New Program
Programs__c Prog = new Programs__c();
prog.Centers_LOOKUP__c=center.Id;
prog.start_date__c=date.parse('08/01/2014');

//New Application
Application__c App = new Application__c();
app.Contact__c=con,Id;

//Inserts
insert prog;    
insert app;

//set Program values
prog.program_manager_lookup__c=pmLookup.Id;
prog.enrollment_counselor__c=eCounselr.Id;
prog.center_owner__c=cOwner.Id;

//update Program and set off trigger
update prog;

//check for expected outcome
System.assertEquals(pmLookup.Id,app.program_manager_lookup__c);
System.assertEquals(eCounselr.Id,app.enrollment_counselor__c);
System.assertEquals(cOwner.Id,app.center_owner__c);

//end test
test.stoptest();
}
 }

If you have to create this kind of test data in most of your test classes, then it would be better to have a static class where you can populate test data and get them into test classes. Hope you have already gone through this .

4
  • were you able to manage the code coverage? I have added some code snippets for the test class that will not fail across sandboxes
    – highfive
    Mar 13, 2014 at 3:46
  • I had actually read your link and removed all of the hardcoding and I've gotten the test to work and my code has 100% percent coverage. The problem now is that when I deploy to production there is a trigger from one of our vendors that sets off the "SOQL queries: 101" error so validation keeps failing. I've marked yours the answer though, thank you for helping me :)
    – mikesalty
    Mar 13, 2014 at 12:53
  • Glad to helping the community. Actually "Limit exceptions" are another topic to discuss. Simply, this is because of you are exceeding the number of queries/DML Statements/ heap size/etc. in a single execution. For the prompt question, avoid having SOQL queries inside loops. Retrieve all your data first and manipulate them inside loops, if there is any update or insert like DML to be executed afterwards, use List and do them in single statement. Follow this guidance. This is where I got started bulkifying my code base.
    – highfive
    Mar 13, 2014 at 16:15
  • Yes, I ran into the limit exception problem in the first couple of days that I was teaching myself apex for triggers and solved it exactly as you state by keeping my SOQL queries outside of the loops. This problem though is that a third party "managed" trigger is causing the SOQL Exception when I try to deploy my triggers. The objects that I needed to create in the test class, the creation of the contact object causes this particular third party trigger to run, and the third party trigger that is pre-existing in my org runs into the SOQL exception. It seems outside of my control to fix.
    – mikesalty
    Mar 13, 2014 at 18:22

You must log in to answer this question.

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