+ Start a Discussion
BarryPlumBarryPlum 

Help with Testing a Trigger

I wrote a trigger in my sandbox and it seems to work exactly as designed.  I moved it over to production and, of course, I need a class to test the trigger.  I created a class and got all the coverage I needed, but the test results aren't coming back as expected.

Here is the trigger code:
Code:
trigger nullTaskType on Task (before insert,before update) {
  private Task[] newTask = Trigger.new;
  if (newTask[0].Type == null) {
   system.debug(newTask[0].subject);
   if (newTask[0].subject.contains('Email') || newTask[0].subject.contains('Brochure') ) {
  newTask[0].Type = 'Email';
 }
 if (newTask[0].subject.contains('Web')) {
  newTask[0].Type = 'Web';
 }
  }
} 

 Here is the Testing Code:
Code:
public class nullTaskType {
 static testMethod void testNullTaskType() {
  Task t1 = new Task (subject='Email');
  system.debug(t1.subject);
  system.debug(t1.type);
  Task t2 = new Task (subject='Brochure');
  Task t3 = new Task (subject='Mass Email');
  Task t4 = new Task (subject='Web');
  Task t5 = new Task (subject='Something Else');
  Task t6 = new Task (type='Email');
  Task[] myTasks = new Task[] {t1,t2,t3,t4,t5,t6};
  insert myTasks;
  system.debug(t1.type);
  system.debug(t2.type);
  system.debug(t3.type);
  system.debug(t4.type);
  system.debug(t5.type);
//  System.assertEquals('Email', t1.type);
//  System.assertEquals('Email', t2.type);
//  System.assertEquals('Email', t3.type);
//  System.assertEquals('Web', t4.type);
  System.assertEquals(null, t5.type);
//  System.assertEquals('Email', t6.type);
 }
}

 
I'm a relative newbie at Apex, so be gentle.
:smileywink:

mikefmikef
BarryPlum:

Looks like your tests are failing because you can't reference the task type using dot notation form the inserted object.

You have to query for the inserted records then test the values.

Code:
Task queryTask = [select Type from Task where subject='Brochure' Limit 1];

System.assertEquals(Email',queryTask.Type);

 Let us know if this was it.



Message Edited by mikef on 05-15-2008 04:32 PM
BarryPlumBarryPlum
That seems like it should work, but I think it's trying to query the actual Task object which is causing a timeout in my Eclipse.

Is there any way to just look at the records I just temporarily inserted to see if they've been updated properly as opposed to querying the whole thing?  Our Task object is huge.
jrotensteinjrotenstein
Shan,

I don't know if this will help with your particular situation, but here's some comments on the code you posted:

Bulk-Safe Trigger
Your Trigger does not appear to be written to handle Bulk Updates. If you are inserting multiple Tasks, your Trigger will be called once, with an array of Tasks in Trigger.new, yet you are only looking at newTask[0]. You should loop through the Trigger.new array and process each Task passed to the Trigger.

Trigger Test
I was writing my first Trigger Test yesterday and was continually getting failures until I realised that I had to retrieve the objects again after the Trigger fired. While the Id field was updated on my original objects, other fields weren't. So, try doing a SELECT to retrieve your inserted tasks (via t1.Id, t2.Id, etc) and test the type values then.

Good luck!

BarryPlumBarryPlum
Good point on the bulk trigger.  I was thinking about one offs, but things like Mass Emails will create a bunch of Tasks at once and may be doing a bulk insert.  It also explains why in my debug messages, it only responds with the first loop.

I'll have to figure out the select statements, thanks for all your help!

Barry


Message Edited by BarryPlum on 05-15-2008 10:42 PM
BarryPlumBarryPlum
Updated to make the trigger bulk-safe... now the debug statements come back as I expect they would.  However, I'm still having a problem selecting the Type from the object.

Here is my code:

Code:
    system.debug(t1.id);  //this comes back as a valid ID
Task queryTask = [select Type from Task where id = :t1.id]; // system.assertEquals('Email',queryTask.Type); system.debug(queryTask.Type); //this comes back as null

Again, please forgive me if this is something I should know.  I'm learning a LOT this week.

Barry

jrotensteinjrotenstein
I had a similar situation and found that I had to retrieve the updated object before testing the fields:
 
Code:
static TestMethod void testIgnoreStageTrigger() {

  Opportunity o = new Opportunity(CloseDate = Date.newInstance(2008, 01, 01), Name = 'Test Opportunity', StageName = Ignore');
  insert o; // This should set StageName = 'New'

  // Reload object
  Opportunity o2 = [select id, StageName, Prevous_Renewals__c from Opportunity where Id = :o.Id];    
  System.assertEquals('New', o2.StageName);
}
 
Only after reloading the object could I get access to the updated fields. The Force.com Cookbook only shows examples that test Exception messages in Triggers, not the objects themselves.
 
This has also been mentioned in another forum post.
BarryPlumBarryPlum
Turns out my code was right after all. 

Thanks for your help.

For any other newbies out there, here is an example of a working Trigger with 90% test coverage.

First the Trigger code:
Code:
trigger nullTaskType on Task (before insert,before update) {
  for (Task newTask : Trigger.new) {
   if (newTask.Type == null) {
    if (newTask.subject.startsWith('Email:') || 
     newTask.subject.startsWith('Brochure')||
     newTask.subject.startsWith('Mass Email') 
     ) {
    newTask.Type = 'Email';
  }
  if (newTask.subject.contains('Website Visit')) {
   newTask.Type = 'Website Visit';
  }
  if (newTask.subject.contains('Unsubscribed') || 
   newTask.subject.contains('Email click through') || 
   newTask.subject.contains('Email Viewed') || 
   newTask.subject.contains('Bounceback') || 
   newTask.subject.contains('Subscribed')
   ) {
    newTask.Type = 'Eloqua Response';
  }
   }
  }
}

 
Now the class to test the trigger:
Code:
public class nullTaskType {
 static testMethod void testNullTaskType() {
  Task t1 = new Task (subject='Email:');
  Task t2 = new Task (subject='Brochure');
  Task t3 = new Task (subject='Mass Email');
  Task t4 = new Task (subject='Website Visit');
  Task t5 = new Task (subject='Unsubscribed');
  Task t6 = new Task (subject='Subscribed');
  Task t7 = new Task (subject='Email click through');
  Task t8 = new Task (subject='Email Viewed');
  Task t9 = new Task (subject='Bounceback');
  Task t10 = new Task (type='Email');
  Task[] myTasks = new Task[]{t1,t2,t3,t4,t5,t6};
  insert myTasks;
  Task queryTask1 = [select Id,type from Task where Id = :t1.Id];
  system.assertEquals('Email',queryTask1.Type);
  Task queryTask2 = [select Id,type from Task where Id = :t2.Id];
  system.assertEquals('Email',queryTask2.Type);
  Task queryTask3 = [select Id,type from Task where Id = :t3.Id];
  system.assertEquals('Email',queryTask3.Type);
  Task queryTask4 = [select Id,type from Task where Id = :t4.Id];
  system.assertEquals('Website Visit',queryTask4.Type);
  Task queryTask5 = [select Id,type from Task where Id = :t5.Id];
  system.assertEquals('Eloqua Response',queryTask5.Type);
  Task queryTask6 = [select Id,type from Task where Id = :t6.Id];
  system.assertEquals('Eloqua Response',queryTask6.Type);
  Task queryTask7 = [select Id,type from Task where Id = :t7.Id];
  system.assertEquals('Eloqua Response',queryTask7.Type);
  Task queryTask8 = [select Id,type from Task where Id = :t8.Id];
  system.assertEquals('Eloqua Response',queryTask8.Type);
  Task queryTask9 = [select Id,type from Task where Id = :t9.Id];
  system.assertEquals('Eloqua Response',queryTask9.Type);
  Task queryTask10 = [select Id,type from Task where Id = :t10.Id];
  system.assertEquals('Email',queryTask10.Type);
 }
}

 
Hope this helps!