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
Niraj Kumar 9Niraj Kumar 9 

Test class for task trigger

Hi guys,
I am need of Test classes.  Here is the trigger.

trigger opportunitycountevent on Event (after insert, after delete) {
    map<id,integer> mopportunityCount = new map<id,integer>();
         integer Countevent =0;
  if (Trigger.isafter){
       if(Trigger.isinsert){

  for(event e :trigger.new) {


    if(e.whatId != null) {
      if(string.valueOf(e.WhatId).left(3) == '006') {
         
         
         if(mopportunityCount.containsKey(e.WhatId)) {
           Countevent  = mopportunityCount.get(e.WhatId);
            }
         
         Countevent  = Countevent   + 1;
      
         mopportunityCount.put(e.whatid,Countevent);
      }
    }
  }
}
 

if(Trigger.isdelete){
  for(event e1 :trigger.old) {
    if(e1.WhatId != null) {
     if(string.valueOf(e1.WhatId).left(3) == '006') {
         
         
         if(mopportunityCount.containsKey(e1.WhatId)) {
           Countevent   = mopportunityCount.get(e1.WhatId);
         }
         Countevent = Countevent - 1;
         mopportunityCount.put(e1.WhatId,Countevent);
      }
    }
  }
}


  if(mopportunityCount.keyset().size()>0) {
    list<opportunity> opportunityToUpdate = new list<opportunity>([SELECT id,Count_of_Activity__c FROM opportunity WHERE Id IN :mopportunityCount.keyset()]);
     for(opportunity o :opportunityToUpdate ) {
     o.Count_of_Activity__c = o.Count_of_Activity__c + mopportunityCount.get(o.id);
    }
   if(opportunityToUpdate.size()>0) {
      update opportunityToUpdate;
    }
   }
  }
  }
 
Best Answer chosen by Niraj Kumar 9
Mahesh DMahesh D
Hi Niraj,

Please find the modified trigger to handle all scenarios of roll up summary:

(1) Followed all scenarios.
(2) Trigger is bulkified.
(3) Naming Convention.
(4) Code coverage is 100%
(4) Tested it in my DE environment and everything looks good.

 
//
// EventTrigger trigger to handle the roll up summary on Opportunity.
//
trigger EventTrigger on Event (after insert, after delete, after undelete, after update) {
    set<Id> oppIdSet = new set<Id>();
    
    if(trigger.isinsert || trigger.isUpdate || trigger.Isundelete){
        for(Event eve: Trigger.new){
            if(eve.whatId.getsObjectType() == Opportunity.sObjectType && (Trigger.isInsert || Trigger.isUndelete || (eve.WhatId != Trigger.oldMap.get(eve.Id).WhatId)))
                oppIdSet.add(eve.WhatId);
        }
    }
    
    if(trigger.isUpdate || trigger.isDelete) {
        for(Event eve: Trigger.old){
            if(eve.whatId.getsObjectType() == Opportunity.sObjectType && (Trigger.isDelete || (eve.WhatId != Trigger.newMap.get(eve.Id).WhatId)))
                oppIdSet.add(eve.WhatId);
        }
    }    
    
    if(!oppIdSet.isEmpty()) {
        List<Opportunity> oppList = [select Id, Count_of_Activity__c, (Select Id from Events) from Opportunity Where ID IN: oppIdSet];
        
        for(Opportunity opp : oppList){
            System.debug('Events--->'+opp.Events.size());
            opp.Count_of_Activity__c = opp.Events.size();
        }
        update oppList;
    }
}

Here is the Test Class:
 
@isTest
private class TestEventTrigger {
    @isTest
    static void testMethodOne() {
        Account acc = new Account();
        acc.Name='Test Account' ;
        insert acc;

        Opportunity opp = new Opportunity();        
        opp.Name = 'Test Apex Opportunity';
        opp.AccountId = acc.Id;
        opp.CloseDate = System.today();
        opp.Stagename = 'Prospect';
        insert opp;
        
        Event eve = new Event();
        eve.Subject = 'Test';
        eve.DurationInMinutes = 30;
        eve.ActivityDateTime = System.now();
        eve.whatId= opp.id;
        insert eve;
        
            
        Opportunity oppNew = [select Id, Count_of_Activity__c from Opportunity where Id =: opp.Id LIMIT 1];
        
        System.assertEquals(1, oppNew.Count_of_Activity__c);
        
        Opportunity oppTwo = new Opportunity();        
        oppTwo.Name = 'Test Apex Opportunity';
        oppTwo.AccountId = acc.Id;
        oppTwo.CloseDate = System.today();
        oppTwo.Stagename = 'Prospect';
        insert oppTwo;
        
        eve.whatId= oppTwo.id;
        update eve;
        
        Opportunity oppTwoNew = [select Id, Count_of_Activity__c from Opportunity where Id =: oppTwo.Id LIMIT 1];
        
        System.assertEquals(1, oppTwoNew.Count_of_Activity__c);
        
    }
}

Please check below post for test classes.
1) https://developer.salesforce.com/page/An_Introduction_to_Apex_Code_Test_Methods

Please follow below salesforce Best Practice for Test Classes :

1. Test class must start with @isTest annotation if class class version is more than 25
2. Test environment support @testVisible , @testSetUp as well
3. Unit test is to test particular piece of code working properly or not .
4. Unit test method takes no argument ,commit no data to database ,send no email ,flagged with testMethod keyword .
5. To deploy to production at-least 75% code coverage is required
6. System.debug statement are not counted as a part of apex code limit.
7. Test method and test classes are not counted as a part of code limit
9. We should not focus on the  percentage of code coverage ,we should make sure that every use case should covered including positive, negative,bulk and single record .
Single Action -To verify that the the single record produces the correct an expected result .
Bulk action -Any apex record trigger ,class or extension must be invoked for 1-200 records .
Positive behavior : Test every expected behavior occurs through every expected permutation , i,e user filled out every correctly data and not go past the limit .
Negative Testcase :-Not to add future date , Not to specify negative amount.
Restricted User :-Test whether a user with restricted access used in your code .
10. Test class should be annotated with @isTest .
11 . @isTest annotation with test method  is equivalent to testMethod keyword .
12. Test method should static and no void return type .
13. Test class and method default access is private ,no matter to add access specifier .
14. classes with @isTest annotation can't be a interface or enum .
15. Test method code can't be invoked by non test request .
16. Stating with salesforce API 28.0 test method can not reside inside non test classes .
17. @Testvisible annotation to make visible private methods inside test classes.
18. Test method can not be used to test web-service call out . Please use call out mock .
19. You can't  send email from test method.
20.User, profile, organization, AsyncApexjob, Corntrigger, RecordType, ApexClass, ApexComponent ,ApexPage we can access without (seeAllData=true) .
21. SeeAllData=true will not work for API 23 version eailer .
22. Accessing static resource test records in test class e,g List<Account> accList=Test.loadData(Account,SobjectType,'ResourceName').
23. Create TestFactory class with @isTest annotation to exclude from organization code size limit .
24. @testSetup to create test records once in a method  and use in every test method in the test class .
25. We can run unit test by using Salesforce Standard UI,Force.com IDE ,Console ,API.
26. Maximum number of test classes run per 24 hour of period is  not grater of 500 or 10 multiplication of test classes of your organization.
27. As apex runs in system mode so the permission and record sharing are not taken into account . So we need to use system.runAs to enforce record sharing .
28. System.runAs will not enforce user permission or field level permission .
29. Every test to runAs count against the total number of DML issued in the process.

Please do let me know if it helps you.

Regards,
Mahesh

All Answers

Amit Chaudhary 8Amit Chaudhary 8
Please check below post to learn About test classes
1) http://amitsalesforce.blogspot.com/search/label/Test%20Class
2) http://amitsalesforce.blogspot.com/2015/06/best-practice-for-test-classes-sample.html
 
@isTest 
public class TriggerTestClass 
{
    static testMethod void testMethodOne() 
	{
		Account testAccount = new Account();
		testAccount.Name='Test Account' ;
		insert testAccount;
		
		Opportunity Opp = new Opportunity();
		Opp.accountId=testAccount.id;
		Opp.name = 'Opportunity Test';
		Opp.CloseDate =  Date.today()+2;
		Opp.StageName = 'Prospecting';
		insert Opp;
			
        Event e = new Event();
        e.Subject = 'Demo ';
        e.Description = 'Event created through Showing/Viewing';
        e.WhatId = Opp.Id;
        e.StartDateTime = system.today() ;
        e.EndDateTime = system.today();
        insert e;
		
		Delete e;	
    }
}



Please follow below salesforce Best Practice for Test Classes :-

1. Test class must start with @isTest annotation if class class version is more than 25
2. Test environment support @testVisible , @testSetUp as well
3. Unit test is to test particular piece of code working properly or not .
4. Unit test method takes no argument ,commit no data to database ,send no email ,flagged with testMethod keyword .
5. To deploy to production at-least 75% code coverage is required
6. System.debug statement are not counted as a part of apex code limit.
7. Test method and test classes are not counted as a part of code limit
9. We should not focus on the  percentage of code coverage ,we should make sure that every use case should covered including positive, negative,bulk and single record .
Single Action -To verify that the the single record produces the correct an expected result .
Bulk action -Any apex record trigger ,class or extension must be invoked for 1-200 records .
Positive behavior : Test every expected behavior occurs through every expected permutation , i,e user filled out every correctly data and not go past the limit .
Negative Testcase :-Not to add future date , Not to specify negative amount.
Restricted User :-Test whether a user with restricted access used in your code .
10. Test class should be annotated with @isTest .
11 . @isTest annotation with test method  is equivalent to testMethod keyword .
12. Test method should static and no void return type .
13. Test class and method default access is private ,no matter to add access specifier .
14. classes with @isTest annotation can't be a interface or enum .
15. Test method code can't be invoked by non test request .
16. Stating with salesforce API 28.0 test method can not reside inside non test classes .
17. @Testvisible annotation to make visible private methods inside test classes.
18. Test method can not be used to test web-service call out . Please use call out mock .
19. You can't  send email from test method.
20.User, profile, organization, AsyncApexjob, Corntrigger, RecordType, ApexClass, ApexComponent ,ApexPage we can access without (seeAllData=true) .
21. SeeAllData=true will not work for API 23 version eailer .
22. Accessing static resource test records in test class e,g List<Account> accList=Test.loadData(Account,SobjectType,'ResourceName').
23. Create TestFactory class with @isTest annotation to exclude from organization code size limit .
24. @testSetup to create test records once in a method  and use in every test method in the test class .
25. We can run unit test by using Salesforce Standard UI,Force.com IDE ,Console ,API.
26. Maximum number of test classes run per 24 hour of period is  not grater of 500 or 10 multiplication of test classes of your organization.
27. As apex runs in system mode so the permission and record sharing are not taken into account . So we need to use system.runAs to enforce record sharing .
28. System.runAs will not enforce user permission or field level permission .
29. Every test to runAs count against the total number of DML issued in the process .


Please let us know if this post will help you
Mahesh DMahesh D
Hi Niraj,

Please find the modified trigger to handle all scenarios of roll up summary:

(1) Followed all scenarios.
(2) Trigger is bulkified.
(3) Naming Convention.
(4) Code coverage is 100%
(4) Tested it in my DE environment and everything looks good.

 
//
// EventTrigger trigger to handle the roll up summary on Opportunity.
//
trigger EventTrigger on Event (after insert, after delete, after undelete, after update) {
    set<Id> oppIdSet = new set<Id>();
    
    if(trigger.isinsert || trigger.isUpdate || trigger.Isundelete){
        for(Event eve: Trigger.new){
            if(eve.whatId.getsObjectType() == Opportunity.sObjectType && (Trigger.isInsert || Trigger.isUndelete || (eve.WhatId != Trigger.oldMap.get(eve.Id).WhatId)))
                oppIdSet.add(eve.WhatId);
        }
    }
    
    if(trigger.isUpdate || trigger.isDelete) {
        for(Event eve: Trigger.old){
            if(eve.whatId.getsObjectType() == Opportunity.sObjectType && (Trigger.isDelete || (eve.WhatId != Trigger.newMap.get(eve.Id).WhatId)))
                oppIdSet.add(eve.WhatId);
        }
    }    
    
    if(!oppIdSet.isEmpty()) {
        List<Opportunity> oppList = [select Id, Count_of_Activity__c, (Select Id from Events) from Opportunity Where ID IN: oppIdSet];
        
        for(Opportunity opp : oppList){
            System.debug('Events--->'+opp.Events.size());
            opp.Count_of_Activity__c = opp.Events.size();
        }
        update oppList;
    }
}

Here is the Test Class:
 
@isTest
private class TestEventTrigger {
    @isTest
    static void testMethodOne() {
        Account acc = new Account();
        acc.Name='Test Account' ;
        insert acc;

        Opportunity opp = new Opportunity();        
        opp.Name = 'Test Apex Opportunity';
        opp.AccountId = acc.Id;
        opp.CloseDate = System.today();
        opp.Stagename = 'Prospect';
        insert opp;
        
        Event eve = new Event();
        eve.Subject = 'Test';
        eve.DurationInMinutes = 30;
        eve.ActivityDateTime = System.now();
        eve.whatId= opp.id;
        insert eve;
        
            
        Opportunity oppNew = [select Id, Count_of_Activity__c from Opportunity where Id =: opp.Id LIMIT 1];
        
        System.assertEquals(1, oppNew.Count_of_Activity__c);
        
        Opportunity oppTwo = new Opportunity();        
        oppTwo.Name = 'Test Apex Opportunity';
        oppTwo.AccountId = acc.Id;
        oppTwo.CloseDate = System.today();
        oppTwo.Stagename = 'Prospect';
        insert oppTwo;
        
        eve.whatId= oppTwo.id;
        update eve;
        
        Opportunity oppTwoNew = [select Id, Count_of_Activity__c from Opportunity where Id =: oppTwo.Id LIMIT 1];
        
        System.assertEquals(1, oppTwoNew.Count_of_Activity__c);
        
    }
}

Please check below post for test classes.
1) https://developer.salesforce.com/page/An_Introduction_to_Apex_Code_Test_Methods

Please follow below salesforce Best Practice for Test Classes :

1. Test class must start with @isTest annotation if class class version is more than 25
2. Test environment support @testVisible , @testSetUp as well
3. Unit test is to test particular piece of code working properly or not .
4. Unit test method takes no argument ,commit no data to database ,send no email ,flagged with testMethod keyword .
5. To deploy to production at-least 75% code coverage is required
6. System.debug statement are not counted as a part of apex code limit.
7. Test method and test classes are not counted as a part of code limit
9. We should not focus on the  percentage of code coverage ,we should make sure that every use case should covered including positive, negative,bulk and single record .
Single Action -To verify that the the single record produces the correct an expected result .
Bulk action -Any apex record trigger ,class or extension must be invoked for 1-200 records .
Positive behavior : Test every expected behavior occurs through every expected permutation , i,e user filled out every correctly data and not go past the limit .
Negative Testcase :-Not to add future date , Not to specify negative amount.
Restricted User :-Test whether a user with restricted access used in your code .
10. Test class should be annotated with @isTest .
11 . @isTest annotation with test method  is equivalent to testMethod keyword .
12. Test method should static and no void return type .
13. Test class and method default access is private ,no matter to add access specifier .
14. classes with @isTest annotation can't be a interface or enum .
15. Test method code can't be invoked by non test request .
16. Stating with salesforce API 28.0 test method can not reside inside non test classes .
17. @Testvisible annotation to make visible private methods inside test classes.
18. Test method can not be used to test web-service call out . Please use call out mock .
19. You can't  send email from test method.
20.User, profile, organization, AsyncApexjob, Corntrigger, RecordType, ApexClass, ApexComponent ,ApexPage we can access without (seeAllData=true) .
21. SeeAllData=true will not work for API 23 version eailer .
22. Accessing static resource test records in test class e,g List<Account> accList=Test.loadData(Account,SobjectType,'ResourceName').
23. Create TestFactory class with @isTest annotation to exclude from organization code size limit .
24. @testSetup to create test records once in a method  and use in every test method in the test class .
25. We can run unit test by using Salesforce Standard UI,Force.com IDE ,Console ,API.
26. Maximum number of test classes run per 24 hour of period is  not grater of 500 or 10 multiplication of test classes of your organization.
27. As apex runs in system mode so the permission and record sharing are not taken into account . So we need to use system.runAs to enforce record sharing .
28. System.runAs will not enforce user permission or field level permission .
29. Every test to runAs count against the total number of DML issued in the process.

Please do let me know if it helps you.

Regards,
Mahesh
This was selected as the best answer
Richard Jimenez 9Richard Jimenez 9
Hi Niraj,

Before you write your unit tests I would suggest a few tweaks to this code:

1. Use one trigger per object per event. Using this pattern will make it easier to manage your triggers if you add more functionality in the future by giving you easier control of the order of execution of your code.

2. Refactor the code so that just the scoping is in the trigger and the processing is in utility class methods.
  • This allows you to keep the trigger looking fairly simple and easier to maintain, so you can add/reuse scoping in the future for other actions.
  • Move your processing logic out of the trigger into utlity class methods so that can then be re-used, eaiser to maintain and can be tested in isolation of you trigger.
3. Do not use hard-coded literals/ids. You can get an object's type or prefix through the schema meta data.

4. Consider the scenario where an existing event is transferred to a different opportunity, or linked to an opportunity after it was created.

5. What do you want to do if the opportunity update fails? If you are updating multiple opportunities do you want the ones you can update without error to complete and just deal with the failed ones or fail the whole update? If an event is transferred from one opp to another you could update one but not the other.

6. Add some comments to help other developers understand quickly its purpose and your logic, just a couple of lines will do. Also, it can help the coder, sometimes having to explain your code can bring out new ideas and thoughts about how you are solving the problem.

7. How are you setting the initial opportuniity activity counts at go-live? Is it a new org or is there a datafix to do?

Just my thoughts... good luck!

Thanks,
Richard.
Niraj Kumar 9Niraj Kumar 9
Hi Mahesh,
trigger is working perfectly, But Test class i am getting error mentioned :::MISSING_ARGUMENT, Id not specified in an update call: []   line 14,21,33,35,36, column 1.

Please help me.

Thanks in Advance.
Mahesh DMahesh D
Hi Niraj,

The above code was tested already in DE environment and it was working fine.

Can you paste your latest Test Class here so that it will be easy to troubleshoot  it.

Regards,
Mahesh
Niraj Kumar 9Niraj Kumar 9
Hi Mahesh,

Finally its work. Thanks for the reply.

Regards,
Niraj kumar.
 
Mahesh DMahesh D
That's perfect Niraj. Please mark it resolved so that it will be helpful to others in the future.

Regards
Mahesh