0

I am very thick when it comes to setting up test classes. How to set up a test class for a very simple trigger like this?

trigger trgr_Key_People on Key_People__c (after insert, after update, after delete) {
    Map<Id, Account> m = new Map<Id, Account>();    
    if(Trigger.isInsert || Trigger.isUpdate)
    {
        // Find the parent contacts
        for (Key_People__c rsp: Trigger.new) 
        {
            m.put(rsp.Account__c, new Account(
                    Id = rsp.Account__c,
                    Key_People__c = ''
                    ));
        }
        }else if (Trigger.isDelete)   
    {
        for (Key_People__c rsp: Trigger.old) 
        {
            m.put(rsp.Account__c, new Account(
                    Id = rsp.Account__c,
                    Key_People__c = ''
                    ));
        }

    }
        String fontColor = 'blue';
        // Query all child objects and re-build the text in the parent contacts
        for (Key_People__c rsp : [
                Select Account__c, first_name__c, last_name__c, portfolio__c,email__c,phone__c,title__c
                from Key_People__c
                where Account__c in :m.keySet()
                order by CreatedDate
                ]) {
            Account c = m.get(rsp.Account__c);


              c.Key_People__c += rsp.first_name__c + ' ' + rsp.last_name__c + '<span style="color:'+fontColor+'; font-weight: bold;"> '+ ' ' + rsp.portfolio__c + '</span> '+ '<br />';
        }
        update m.values();
}

This is my attempt at setting up data. I haven't gotten that correct without errors. It doesn't like my recordtype. I get the error "Invalid initial expression type for field RecordType, expecting: RecordType (or single row query result of that type)"

@isTest 
public class test_BOG_Committee_Report {

    static testMethod void test_BOG_Committee_Report() 
    {
       Account a1 = new Account(Name='AccountTest1',RecordType='01220000000MFXn'); 
       Account a2 = new Account(Name='AccountTest2',RecordType='01220000000MFXn');  
       Account a3 = new Account(Name='AccountTest3',RecordType='01220000000MFXn');    

       Contact c1 = new Contact(Name='ContactTest1',RecordType='01220000000MEBo',Constituent_Code__c='Donor',Account='AccountTest1');
       Contact c2 = new Contact(Name='ContactTest2',RecordType='01220000000MEBo',Constituent_Code__c='Donor',Account='AccountTest2'); 
       Contact c3 = new Contact(Name='ContactTest3',RecordType='01220000000MEBo',Constituent_Code__c='Donor',Account='AccountTest3');  

       BOG_Membership__c bm = new BOG_Membership__c(Contact__c='ContactTest1', RecordType='01220000000MEHG');


       // Insert 
       insert bm;

       // Retrieve
       bm = [SELECT Contact__c FROM BOG_Membership__c WHERE Id =:bm.Id];

       Test.startTest(); 

       Test.stopTest();    
    }
}
  • Have you tried to write the test class? I think you have basic three scenarios of insert, update and delete. Do simple DML operation so that your trigger fired and assert values. I advice first you try and put the test class code so that community helps more appropriately. – Anurag Bhardwaj Jul 24 '16 at 9:01
  • I pasted my test class in progress. – Apex N-u-b Jul 24 '16 at 13:05
  • To start it should be recordtypeid that you are assigning. Also you should never hardcode the ids – Eric Jul 24 '16 at 14:31
1

There are a few different problems with your approach in your test code.

  1. Your trigger runs after insert, after update, and after delete of the Key_People__c object, but your test code isn't inserting, updating, or deleting any Key_People__c object records.
  2. RecordType should be RecordTypeId
  3. You should never hard-code Ids, even in test classes, since the Ids will likely change between dev and production, resulting in failed test classes. Instead, you should get the RecordTypeId from the database directly. You can achieve this with a simple SOQL query:

Id RecordTypeId = [SELECT Id FROM RecordType WHERE SObjectType='OBJECT_NAME_HERE' AND Name='RECORDTYPE_NAME_HERE' LIMIT 1];

This code is by no means tested, but hopefully will help you get started in the right direction. First thing to note is the @testSetup method. This is a newer feature to Salesforce that allows you to setup your test data only ONCE per test class, and then use it fresh in all of your following methods.

Then, once we've established our record type Ids, test data, etc, we then have 2 separate test methods that handle different conditions for your apex class.. one is your update condition, where you modify the record and update it to trigger your code. The next is the delete condition, where you delete a record to trigger your code:

@isTest 
public class test_BOG_Committee_Report {

    @testSetup static void test_DataSetup() 
    {

    Id acctRTypeId = [SELECT Id FROM RecordType WHERE ObjectType='Account' AND Name='RECORDTYPE_NAME_HERE' LIMIT 1];
    Id contactRTypeId = [SELECT Id FROM RecordType WHERE ObjectType='Contact' AND Name='RECORDTYPE_NAME_HERE' LIMIT 1];
    Id bmRTypeId = [SELECT Id FROM RecordType WHERE ObjectType='BOG_Membership__c' AND Name='RECORDTYPE_NAME_HERE' LIMIT 1];



    List<Account> acctList = new List<Account>();
    List<Contact> contactList = new List<Contact>();
    List<Key_People__c> kpList = new List<Key_People__c>();

       Account a1 = new Account(Name='AccountTest1',RecordTypeId=acctRTypeId); 
       Account a2 = new Account(Name='AccountTest2',RecordTypeId=acctRTypeId);  
       Account a3 = new Account(Name='AccountTest3',RecordTypeId=acctRTypeId);    
       acctList.add(a1);
       acctList.add(a2);
       acctList.add(a3);
       insert acctList;

       Contact c1 = new Contact(Name='ContactTest1',RecordTypeId=contactRTypeId,Constituent_Code__c='Donor',Account=a1);
       Contact c2 = new Contact(Name='ContactTest2',RecordTypeId=contactRTypeId,Constituent_Code__c='Donor',Account=a2); 
       Contact c3 = new Contact(Name='ContactTest3',RecordTypeId=contactRTypeId,Constituent_Code__c='Donor',Account=a3);  
       contactList.add(c1);
       contactList.add(c2);
       contactList.add(c3);
       insert contactList

       Key_People__c kp1 = new Key_People__c(Name='KPTest1',Account__c=a1);
       Key_People__c kp2 = new Key_People__c(Name='KPTest2',Account__c=a2);
       Key_People__c kp3 = new Key_People__c(Name='KPTest3',Account__c=a3);
       kpList.add(kp1);
       kpList.add(kp2);
       kpList.add(kp3);
       insert kpList;

       BOG_Membership__c bm = new BOG_Membership__c(Contact__c=c1, RecordTypeId=bmRTypeId);

       // Insert 
       insert bm;

       // Retrieve
       bm = [SELECT Contact__c FROM BOG_Membership__c WHERE Id =:bm.Id];    
    }

    static testMethod void test_Update() {
      // Do some modifications to your Key_People__c records...

      kp1.Some_Field__c = 'some value';

      Test.StartTest();
      update kp1;
      Test.StopTest();

    }

    static testMethod void test_Delete() {
    // Do some modifications?? Possibly... then Delete

    Test.StartTest();
    delete kp2;
    Test.StopTest();

    }
}
  • Many thanks. I had to modify it a little to get past the errors but after saving it gives me 0 code coverage. Why? – Apex N-u-b Jul 25 '16 at 7:20
  • @ApexN-u-b I see that you marked my answer as best, but your comment from yesterday says you are still getting 0 code coverage. Do you still need some help or did you get it figured out from my example code? – Morgan Marchese Jul 26 '16 at 15:36
0

Testing is the integrated part of Apex or any other application development. In Apex, we have separate test classes to develop for all the unit testing.

Creating Test Class

Data Creation

We need to create data for test class in our test class itself. Test class by default does not have access to organization data but if you set @isTest(seeAllData = true) then it will have the access to organization's data as well.

@isTest annotation

By using this annotation, you declared that this is a test class and it will not be counted against the organization's total code limit.

testMethod keyword

Unit test methods are the methods which does no take arguments, commit no data to the database, send no emails, and are declared with the testMethod keyword or the isTest annotation in the method definition. Also, test methods must be defined in test classes, that is, classes annotated with isTest.

Test.startTest() and Test.stopTest()

These are the standard test methods which are available for test classes. These methods contain the event or action for which we would be simulating our test.This also provides separate governor limit to the code which is in start and stop block.

System.assert()

This method checks the desired output with the actual.

public class testingClass{
    static testMethod void testingClass(){

        // the sample code could be,

        //insert sampleData based on the conditions as per logic in your code

        // Now invoke a Test.startTest() to perform your testing

        // Perform necessary DML(Insert/Update/Delete) for object Key_People__c 
        // The trigger code will get invoke after executing a DML operation

        // Test.stopTest()

        // Write assert statement to verify results
    }
}

Apex Test Methods

How to write a unit-test / test class for trigger?

  • This is good but I am having a hard time making a test class just from what it says. – Apex N-u-b Jul 24 '16 at 13:06
0

For any relationship field, you can always get (and set) either the Id or the actual record. Setting it in this way requires a different structure than you have. More on that later.

Most standard relationships share a naming convention similar to the following:

Id parentId = record.RecordTypeId;
SObject parent = record.RecordType;

The same goes for AccountId and Account. Setting the value by Id is simpler in many cases. To set using the relationship you need to reference an external key. I can't remember if DeveloperName is external or not, but if it is you could do either of the following (query approach works either way).

RecordType rt = [SELECT Id FROM RecordType WHERE DeveloperName = '<devname>'];
record.RecordTypeId = rt.Id;
// OR
record.RecordType = new RecordType(DeveloperName='<devname>');

Advantage of the query approach is it doesn't matter if the field is external id. It's a good idea to use a unique field if at all possible, though.

Note that using hard-coded ids should be avoided at all costs.

  • For recordtypeid specifically if u do not need developer name you can use describe to get the ids by name without the query. – Eric Jul 25 '16 at 7:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.