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
levi6dblevi6db 

100% Coverage in Sandbox, 0% in Production???

Hi all,

 

I am trying to move a Trigger into Production but I am getting a 0% coverage when I validate it through Eclipse/Force.com.  I have 100% coverage when I run all tests in the sandbox.

 

The trigger will move the owner of an event to match the new lead owner once the lead is moved from a lead queue owner.

 

Here is the trigger and class.  I already received help from the discussion board on the trigger, thanks again in advance.

 

Any suggestions?

 

 

**** Trigger ****

trigger ownerupdate on Lead (after Update) {

List<Event> aplist = new List<Event>();

for(Lead t : Trigger.new){

IF(
(t.LeadSource == 'Telemarketing'
    && t.OwnerId != '00G30000001iNeKEAU' 
     && t.OwnerId != '00G30000001iNtxEAE'
      && t.OwnerId != '00G30000001uiO5'
       && t.OwnerId != '00G30000001iCwM'
        && t.OwnerId != '00G30000001uh70'
         && t.OwnerId != '00G30000001iNt5EAE'
          && t.OwnerId != '00G30000001ui8wEAA'
           && t.OwnerId != '00G30000001iNuC'
            && t.OwnerId != '00G30000001iNsL'
             && t.OwnerId != '00G30000001iNvZ'
              && t.OwnerId != '00G30000001jtEi'
               && t.OwnerId != '00G30000001tiXR'
                && t.OwnerId != '00G30000001ui8w'
                 && t.OwnerId != '00G30000001iNt5'
))

{List<Event> aps = [Select WhoId, Whatid, OwnerId from Event where WhoId = :t.Id];
   for (Event ap : aps)
   {       
      ap.OwnerId = t.OwnerId;

      aplist.add( ap );
   }

}}
update aplist;
}
trigger ownerupdate on Lead (after Update) {
    && t.OwnerId != '00G30000001iNeKEAU' 
**** Class Test Method **** public class ownerupdate { static testMethod void T1() { Id lId; Id eId; //CREATE 1 LEAD Lead l = new Lead(); l.LeadSource = 'Telemarketing'; l.lastname = 'Doe'; l.company = 'Test Company'; l.ownerId = '00530000003IFwV'; l.status = 'Open'; l.market__c = 'Atlanta'; Database.insert(l); lId = l.Id; //CREATE 2 Event Event e = New Event (); e.DurationInMinutes = 60; e.ActivityDateTime = date.today(); e.ownerId = l.ownerId; e.WhoId = l.Id; Database.SaveResult result = Database.insert(e); eId = e.Id; update e; {List<Lead> aps = [Select Leadsource, owner_convert_queue__c, id, OwnerId from Lead where id = :e.whoId]; system.debug('@@@apo=' + aps); } }}

 

Alex

 

Best Answer chosen by Admin (Salesforce Developers) 
levi6dblevi6db

Here is what finally worked.  Thank you for your help SFMaverick!

 

Class:

 

public class ownerupdateTrigger {
static testMethod void e1() {
    Id lId;
    Id eId;
        
     //CREATE 1 LEAD
     
    Lead l = new Lead();
    l.Web_Ref_Number__c = 'BAO Lead';
    l.LeadSource = 'Telemarketing';
    l.lastname = 'Doe';
    l.company = 'Test Company';
    l.ownerId = '00530000003IFwV';
    l.status = 'Open';
    l.Lead_Convert__c = TRUE;
    l.market__c = 'Atlanta';
    Database.insert(l);
    lId = l.Id;
    
          
    //CREATE 2 Event
    
      Event e = New Event ();
      e.DurationInMinutes     = 0;
      e.StartDateTime         = date.today();
      e.EndDateTime           = date.today();
      e.ActivityDateTime      = date.today();
      
      e.WhoId                 = l.Id;
    
     Database.insert(e);
     
     eId = e.Id;
        
     update e;
     
     
      Lead ql = [Select id,Leadsource,Status,OwnerId from Lead where Id = :l.Id limit 1];
      system.debug('@@@ql=' + ql);
      
      l.ownerId = '00530000001rFmX';
      
      update l;
 
     Event qe = [Select id,WhoId from Event where id = :e.id limit 1];
     system.debug('@@@ql=' + qe);
     
     e.ownerId = l.ownerId;
     
     update e;
     
     
    
          
 {List<Lead> aps = [Select Leadsource, id, OwnerId from Lead
  where id = :e.whoId];
 system.debug('@@@apo=' + aps);
}
}}

 

 

Trigger:

 

trigger ownerupdate on Lead (after Update) {

List<Event> aplist = new List<Event>();

for(Lead t : Trigger.new){

IF(
(t.LeadSource == 'Telemarketing'
    && t.OwnerId != '00G30000001iNeK' 
     && t.OwnerId != '00G30000001iNtxEAE'
      && t.OwnerId != '00G30000001uiO5'
       && t.OwnerId != '00G30000001iCwM'
        && t.OwnerId != '00G30000001uh70'
         && t.OwnerId != '00G30000001iNt5EAE'
          && t.OwnerId != '00G30000001ui8wEAA'
           && t.OwnerId != '00G30000001iNuC'
            && t.OwnerId != '00G30000001iNsL'
             && t.OwnerId != '00G30000001iNvZ'
              && t.OwnerId != '00G30000001jtEi'
               && t.OwnerId != '00G30000001tiXR'
                && t.OwnerId != '00G30000001ui8w'
                 && t.OwnerId != '00G30000001iNt5'
))

{List<Event> aps = [Select WhoId, Whatid, OwnerId from Event where WhoId = :t.Id];
   for (Event ap : aps)
   {       
      ap.OwnerId = t.OwnerId;

      aplist.add( ap );
   }

}}
update aplist;
}

 

 

All Answers

dhoechstdhoechst

How are you trying to move it? Are you deploying to production or just copying and pasting the code? I'm guessing you are doing a copy and paste. Try deploying your two files from Sandbox to Production. Right click on your Sandbox project in the Force.com IDE, go to Force.com and select Deploy to Server... Follow the steps and it should deploy.

SFmaverickSFmaverick

Few things, I would suggest more indenting to clean up your code a bit, the way you have it, it's not as easy to tell which { each } is related to.

 

You don't want all that code in your trigger, you want to move as much of that as you can to the class that has the test method.

 

Do something like this for your trigger:

trigger ownerupdate on Lead (after Update) {

Lead[] t = Trigger.new;
Leads.OwnerUpdate(t);

}

 

 

and your test class should turn into this:

 

 

public class Leads{

public static void OwnerUpdate(Lead[] ts){
List<Event> aplist = new List<Event>();
for(Lead t : ts){ IF( (t.LeadSource == 'Telemarketing'&& t.OwnerId != '00G30000001iNeK' && t.OwnerId != '00G30000001iNtxEAE' && t.OwnerId != '00G30000001uiO5' && t.OwnerId != '00G30000001iCwM' && t.OwnerId != '00G30000001uh70' && t.OwnerId != '00G30000001iNt5EAE' && t.OwnerId != '00G30000001ui8wEAA' && t.OwnerId != '00G30000001iNuC' && t.OwnerId != '00G30000001iNsL' && t.OwnerId != '00G30000001iNvZ' && t.OwnerId != '00G30000001jtEi' && t.OwnerId != '00G30000001tiXR' && t.OwnerId != '00G30000001ui8w' && t.OwnerId != '00G30000001iNt5' )) {List<Event> aps = [Select WhoId, Whatid, OwnerId from Event where WhoId = :t.Id]; for (Event ap : aps) { ap.OwnerId = t.OwnerId; aplist.add( ap ); } }}
update aplist; }
//Test Method static testMethod void T1() { Id lId; Id eId; //CREATE 1 LEAD Lead l = new Lead(); l.LeadSource = 'Telemarketing'; l.lastname = 'Doe'; l.company = 'Test Company'; l.ownerId = '00530000003IFwV'; l.status = 'Open'; l.market__c = 'Atlanta'; Database.insert(l); lId = l.Id; //CREATE 2 Event Event e = New Event (); e.DurationInMinutes = 60; e.ActivityDateTime = date.today(); e.ownerId = l.ownerId; e.WhoId = l.Id; Database.SaveResult result = Database.insert(e); eId = e.Id; update e; {List<Lead> aps = [Select Leadsource, owner_convert_queue__c, id, OwnerId from Lead where id = :e.whoId]; system.debug('@@@apo=' + aps); } }

}

 

Upload the class to the server before the trigger and all should go well. try it on your sandbox first!

 

 

levi6dblevi6db

I updated the Trigger above to make the fields easier to see.

 

dhoechst - I did the steps that you suggested already.  For some reason it is just not liking the code.

 

 

SFmaverickSFmaverick

I did the rewriting for you...

 

Just use the code I put above for your class and trigger and it should all work.

levi6dblevi6db

For the Trigger, I received this error:

 

 

Error: Compile Error: Method does not exist or incorrect signature: Leads.ownerupdate(LIST<Lead>) at line 4 column 1	

 

 

For the Class, I received this error (Line 27 = update aplist;:

 

 

Error: Compile Error: expecting right curly bracket, found 'update' at line 27 column 0	

 

 

Thanks,

Alex

SFmaverickSFmaverick

Recopy / paste what I have above, I accidentally left in an extra curly bracket which was likely causing those issues so I edited it out!

levi6dblevi6db

Thank you for helping me out, I really appreciate it.

 

One more error:

 

 

Error: Compile Error: Only top-level class methods can be declared static at line 34 column 24	

 

 

Thanks,

Alex

SFmaverickSFmaverick

Sorry I rushed through this each time, I forgot to take out your old class declaration...

 

I fixed it above, just recopy/paste the second block of code, the trigger remained the same.

 

:)

levi6dblevi6db

One more...I totally understand if you grow tired of this :)

 

 

	Error: Compile Error: Initial term of field expression must be a concrete SObject: LIST<Lead> at line 18 column 77	

 

Thanks,

Alex

 

SFmaverickSFmaverick

Can you please highlight the line of code that's giving the error in red, I don't have that code in the editor to see the line number.

levi6dblevi6db

Sorry about that:

 

 

Error: Compile Error: Initial term of field expression must be a concrete SObject: LIST<Lead> at line 18 column 77	



{List<Event> aps = [Select WhoId, Whatid, OwnerId from Event where WhoId = :t.Id];

 

Thanks,

Alex

 

SFmaverickSFmaverick

Once again recopy the bottom section of code;

SFmaverickSFmaverick

Let me know if that works. If so, please accept the post with all the code in it as the answer so it might help others in the future. Thanks :)

levi6dblevi6db

Ok, cool, I was able to save the Class and Trigger.

 

The Trigger is working now, but when I try and deploy the two, I get the following error:

 

 

Save error: File name mismatch with class name: Leads  

ownerupdate.cls

Owner Update Trigger/src/classes

line 0

Force.com save problem

 

The Class and Trigger have different names now.  I also get 0% coverage when I run the all tests in the Sandbox vs the Class.

 

Thanks,

Alex

 

SFmaverickSFmaverick

 

public class LeadsCLASS{

    public static void OwnerUpdate(Lead[] ts){
        List<Event> aplist = new List<Event>();

        for(Lead t : ts){
            IF(
                (t.LeadSource == 'Telemarketing'&& t.OwnerId != '00G30000001iNeK' &&
                 t.OwnerId != '00G30000001iNtxEAE' && t.OwnerId != '00G30000001uiO5' &&
                 t.OwnerId != '00G30000001iCwM' && t.OwnerId != '00G30000001uh70' &&
                 t.OwnerId != '00G30000001iNt5EAE' && t.OwnerId != '00G30000001ui8wEAA' &&
                 t.OwnerId != '00G30000001iNuC' && t.OwnerId != '00G30000001iNsL' &&
                 t.OwnerId != '00G30000001iNvZ' && t.OwnerId != '00G30000001jtEi' &&
                 t.OwnerId != '00G30000001tiXR' && t.OwnerId != '00G30000001ui8w' &&
                 t.OwnerId != '00G30000001iNt5')
              )

            {List<Event> aps = [Select WhoId, Whatid, OwnerId from Event where WhoId = :t.Id];
               for (Event ap : aps){       
                      ap.OwnerId = t.OwnerId;
                      aplist.add( ap );
               }
            }
        }
        update aplist;

    }

//Test Method

    static testMethod void T1() {
        Id lId;
        Id eId;
        
         //CREATE 1 LEAD
     
        Lead l = new Lead();
        l.LeadSource = 'Telemarketing';
        l.lastname = 'Doe';
        l.company = 'Test Company';
        l.ownerId = '00530000003IFwV';
        l.status = 'Open';
        l.market__c = 'Atlanta';
        Database.insert(l);
        lId = l.Id;
    
          
        //CREATE 2 Event
    
          Event e = New Event ();
          e.DurationInMinutes     = 60;
          e.ActivityDateTime      = date.today();
          e.ownerId               = l.ownerId;
          e.WhoId                 = l.Id;
    
         Database.SaveResult result = Database.insert(e);
            eId = e.Id;
        
              update e;
          
         {List<Lead> aps = [Select Leadsource, owner_convert_queue__c, id, OwnerId from Lead
          where id = :e.whoId];
             system.debug('@@@apo=' + aps);
         }
    }

}

 Use that for the class and make sure the file name you give it is something that will be unique, for example LeadsCLASS.

 

 

trigger OwnerUpdate on Lead (after Update) {

Lead[] t = Trigger.new;
LeadsCLASS.OwnerUpdate(t);

}

 

 

Use that for the trigger and make sure the file name you give it is something that will be unique, go with LeadsUpdateTRIGGER.

 

It's good practice to suffix your triggers because if you write any visualforce pages, you'll also have controllers and you'll want to easily distinguish them. I'm thinking the name you chose for your trigger or class is already taken.

 

SFmaverickSFmaverick

Did that work for you Levi?

levi6dblevi6db

I went back in and reloaded the class and trigger into eclipse and renamed them like you said.  The Class loads just fine, but the Trigger still fails when I try to deploy it.  

 

Failures and Warnings: LeadsUpdateTRIGGER :  Test Coverage of selected Apex Trigger is 0%, at least 1% test coverage is required.

 

 

Also, in Sandbox & Production, when I 'Run All Tests' I get 0% coverage:

 

"Average test coverage across all Apex Classes and Triggers is 0%, at least 75% test coverage is required"

SFmaverickSFmaverick

Is the trigger working fine in the sandbox?

levi6dblevi6db

Yes, it is working great in Sandbox.

SFmaverickSFmaverick

Your test method is likely not adhering to validation rules that you have on your leads and events.

 

As an example, I had this same issue when I was trying to deploy a trigger on a custom object Shift__c because the values I inserted into the fields in the test record failed my validation rules. My shift__c.position__c had to be equal to one of 4 literal values, I didn't do that, it failed to insert the shift so it failed to ever call my trigger, which is what led to 0% coverage.

 

What validation rules do you have on your Leads and events upon inserting and updating them?

levi6dblevi6db

 

Lead Validation Rules:
1. Lead Source = Campaign - you must add a campaign
2. Lead Source = Employee Referral - you must add the employee name
3. Lead Source = Other - You must enter the lead source name (to a text field)
4. Lead Source = Partner - You must add the partner account
Event/Task Validation Rules:
None
Lead Workflows:
1. Disqualified Lead = you must add the disqualified reason
Event/Task Workflows:
1. Cancelled Event Update = If an event is cancelled, update the Subject to 'Subject - Cancelled'

 

Lead Validation Rules:
1. Lead Source = Campaign - you must add a campaign

2. Lead Source = Employee Referral - you must add the employee name

3. Lead Source = Other - You must enter the lead source name (to a text field)

4. Lead Source = Partner - You must add the partner account


Event/Task Validation Rules:

None


Lead Workflows:
1. Disqualified Lead = you must add the disqualified reason


Event/Task Workflows:
1. Cancelled Event Update = If an event is cancelled, update the Subject to 'Subject - Cancelled'

SFmaverickSFmaverick

Try to (in production) create a lead and an event on that lead just like the one you're creating in your test method. Check if it throws any errors at you. It should, I believe that's where the problem is.

levi6dblevi6db

I created a new Lead with the info provided, then created an Event the same way.  I did not get any errors.

 

I am stumped.

 

I did notice that we have an auto assignment rule in place for Telemarketing leads that come from the web.

 

If the Lead comes in with the Web Ref Number field populated with "IIO", then it is assigned to the Telemarketing Queue.

 

The field is called: Web_Ref_Number__c

It is a text field, 50 character length

The field would only have these characters in it: IIO Lead

 

levi6dblevi6db

Here is what finally worked.  Thank you for your help SFMaverick!

 

Class:

 

public class ownerupdateTrigger {
static testMethod void e1() {
    Id lId;
    Id eId;
        
     //CREATE 1 LEAD
     
    Lead l = new Lead();
    l.Web_Ref_Number__c = 'BAO Lead';
    l.LeadSource = 'Telemarketing';
    l.lastname = 'Doe';
    l.company = 'Test Company';
    l.ownerId = '00530000003IFwV';
    l.status = 'Open';
    l.Lead_Convert__c = TRUE;
    l.market__c = 'Atlanta';
    Database.insert(l);
    lId = l.Id;
    
          
    //CREATE 2 Event
    
      Event e = New Event ();
      e.DurationInMinutes     = 0;
      e.StartDateTime         = date.today();
      e.EndDateTime           = date.today();
      e.ActivityDateTime      = date.today();
      
      e.WhoId                 = l.Id;
    
     Database.insert(e);
     
     eId = e.Id;
        
     update e;
     
     
      Lead ql = [Select id,Leadsource,Status,OwnerId from Lead where Id = :l.Id limit 1];
      system.debug('@@@ql=' + ql);
      
      l.ownerId = '00530000001rFmX';
      
      update l;
 
     Event qe = [Select id,WhoId from Event where id = :e.id limit 1];
     system.debug('@@@ql=' + qe);
     
     e.ownerId = l.ownerId;
     
     update e;
     
     
    
          
 {List<Lead> aps = [Select Leadsource, id, OwnerId from Lead
  where id = :e.whoId];
 system.debug('@@@apo=' + aps);
}
}}

 

 

Trigger:

 

trigger ownerupdate on Lead (after Update) {

List<Event> aplist = new List<Event>();

for(Lead t : Trigger.new){

IF(
(t.LeadSource == 'Telemarketing'
    && t.OwnerId != '00G30000001iNeK' 
     && t.OwnerId != '00G30000001iNtxEAE'
      && t.OwnerId != '00G30000001uiO5'
       && t.OwnerId != '00G30000001iCwM'
        && t.OwnerId != '00G30000001uh70'
         && t.OwnerId != '00G30000001iNt5EAE'
          && t.OwnerId != '00G30000001ui8wEAA'
           && t.OwnerId != '00G30000001iNuC'
            && t.OwnerId != '00G30000001iNsL'
             && t.OwnerId != '00G30000001iNvZ'
              && t.OwnerId != '00G30000001jtEi'
               && t.OwnerId != '00G30000001tiXR'
                && t.OwnerId != '00G30000001ui8w'
                 && t.OwnerId != '00G30000001iNt5'
))

{List<Event> aps = [Select WhoId, Whatid, OwnerId from Event where WhoId = :t.Id];
   for (Event ap : aps)
   {       
      ap.OwnerId = t.OwnerId;

      aplist.add( ap );
   }

}}
update aplist;
}

 

 

This was selected as the best answer