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

Trigger - test class: Even your example fails !!!!!! lol

I have a trigger that works perfect in development. It's been done for about 1 week now.

I cannot get it deployed because I cannot build the test.

Hey, I've asked for help from this forum and no help - that worked
I've poured over every scrap of documentation.

I found an example and went back to it.
This time, I'm going to make a package out of your example
So here goes ...
This is all from your documentation.
First - the Trigger
Second - the Class.
Your documentation says this is what you need.
I made a trigger and compiled it - ok.
I made the class and compiled it - ok.
Went to make a package so I can get this into  P R O D U C T I ON   -   and FAILURE !!!!!!!!!!!!!!

From your PDF - The_World's_First_On-Demand_Programming_Language

The Trigger:

trigger blockDuplicates_tgr on Lead bulk(before insert, before update) {
* begin by building a map which stores the (unique) list of leads
* being inserted/updated, using email address as the key.
Map<String, Lead> leadMap = new Map<String, Lead>();
for (Lead lead : {
if (lead.Email != null) { // skip null emails
/* for inserts OR
* updates where the email address is changing
* check to see if the email is a duplicate of another in
* this batch, if unique, add this lead to the leadMap
if ( System.Trigger.isInsert ||
(System.Trigger.isUpdate &&
lead.Email != System.Trigger.oldMap.get(lead.Id).Email)) {

if (leadMap.containsKey(lead.Email)) {
lead.Email.addError('Another new lead has the same email address.');
} else {
leadMap.put(lead.Email, lead);

/* Using the lead map, make a single database query,
* find all the leads in the database that have the same email address as
* any of the leads being inserted/updated.
for (Lead lead : [select Email from Lead where Email IN :leadMap.KeySet()]) {
Lead newLead = leadMap.get(lead.Email);
newLead.Email.addError('A lead with this email address already exists.');

 Now : The Test Class.

public class testBlockDuplicatesLeadTrigger {

static testMethod void testDuplicateTrigger(){

Lead[] l1 =new Lead[]{
new Lead( Email='', LastName='Simpson', Company='fox' )
insert l1; // add a known lead

Lead[] l2 =new Lead[]{
new Lead( Email='', LastName='Simpson', Company='fox' )
// try to add a matching lead
try { insert l2; } catch ( System.DmlException e) {
system.assert(e.getMessage().contains('first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, A lead with this email address already exists'),

// test duplicates in the same batch
Lead[] l3 =new Lead[]{
new Lead( Email='', LastName='Simpson', Company='fox' ),
new Lead( Email='', LastName='Simpson', Company='fox' )
try { insert l3; } catch ( System.DmlException e) {
system.assert(e.getMessage().contains('first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Another new lead has the same email'),


// test update also
Lead[] lup = new Lead[]{
new Lead( Email='', LastName='Simpson', Company='fox' )
insert lup;
Lead marge = [ select id,Email from lead where Email = '' limit 1];
marge.Email = '';

try { update marge; } catch ( System.DmlException e) {
system.assert(e.getMessage().contains('irst error: FIELD_CUSTOM_VALIDATION_EXCEPTION, A lead with this email address already exists'),


  AGAIN : the above compiled.

With the two items above saving correctly, let's create a package.
Create a new unmanaged package and add the two items above.
Click 'upload'.


- - - Here is what it says

There are problems that prevent this package from being uploaded.

Item TypeNameProblem
Apex ClasstestBlockDuplicatesLeadTrigger.testDuplicateTrigger()System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, blockDuplicates: execution of BeforeInsert

caused by: System.NullPointerException: Attempt to de-reference a null object

Trigger.blockDuplicates: line 14, column 32
Class.testBlockDuplicatesLeadTrigger.testDuplicateTrigger: line 6, column 9

    HELLO - HOUSTON - WE HAVE A PROBLEM.  Your own example doesn't work !!!!!!!!!!!!!!!!!!!!!!

    I have spent the last 3-4 weekends on SalesForce. I've been working on this thing overtime about 3 nights a week.
    Without getting our trigger up into production - I WILL report to my management that Salesforce is a FAILURE.

    We are a LARGE account. My suggestion to executive level is
    (1) You write the test for free, or
    (2) You allow the trigger to work without a test, or
    (3) We cancel the Purchase order and look at other CRM products.

    We have called our account executive who put us in touch with a 'specialist'.

   The specialist said that you don't even use tests anymore !

    Something is going to give here.

    Can you at LEAST make your example work so that I have SOMETHING to go by.

    Time and Date: Saturday, April 19, 2008 at 4:30pm

Will you at least get your example to work?  What are we going to do.

Monday, I go to my managment and raise big alarms and declare a failure.

I am stopping work on SalesForce on my own time.

Taking a look at Netsuite and Oracle.

However, do expect to hear about this from the top-down, because big $ have been paid for a failure.

I followed your documented steps in my dev org and created both the trigger and test class.  I then uploaded these per your instructions as an unmanaged package:

No issues were encountered with creating or deploying this via packaging.  I also validated the duplicate functionality on my consuming org.

Reviewing your error: "CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, blockDuplicates: execution of BeforeInsert" – this seems to reference another trigger.  Can you post the "blockDuplicates" trigger code?  Your post includes "blockDuplicates_tgr" not "blockDuplicates", perhaps this is causing the issue.

You are not being ignored, I'm looking into this.

I am encountering something strange too. Receiving the following exception in a live org, whereas it worked fine in dev.
Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger returnSaved caused an unexpected exception, contact your administrator: returnSaved: execution of AfterInsert caused by: System.DmlException: Update failed. First exception on row 0 with id a072000000360hyAAA; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, returnSaved: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id a0920000001c7IVAAY; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Phone- and Faxnumbers should start with a "+" and contain nothing else then numbers: [Id] Trigger.returnSaved: line 58, column 5: Trigger.returnSaved: line 42, column 13
The trigger is on a custom object, the validation rule complained about above is on Account and Contact objects. Code of this trigger as follows:
// -------------------------------------------------------------------------------------------
// This trigger makes sure that changes to return amounts/quantities (based on returns
// under the order are aggregated at Budget level. This is necessary because Master detail detail
// relations are unsupported by SFDC, as a consequence Roll-up will not work.
// -------------------------------------------------------------------------------------------
trigger returnSaved on Return__c (after insert, after update, after delete, 
after undelete) {
 // Set old numbers to zero
 Double qtyOld = 0;
 Double amOld =  0;
 Double totalAmountNewReturn = 0;
 if(Trigger.isUpdate) {
  // Retrieve old values in case of an update
  Return__c retOld = Trigger.old[0];
  qtyOld = retOld.Total_Quantity_Returned__c;
  amOld =  retOld.Total_Amount_Returned__c;
 Return__c retNew;
 if(!Trigger.isDelete) {
  retNew =[0];
 } else {
  retNew = Trigger.old[0];

 // Fetch the Budget which we are updating.
 CI_Order__c ord = [SELECT Id,Budget__c FROM CI_Order__c WHERE Id = :retNew.Order__c  LIMIT 1];
 Budget__c bud = [SELECT Id,Total_Amount_Returns__c,Total_Quantity_Returns__c FROM Budget__c WHERE Id = :ord.Budget__c  LIMIT 1]; 
 // Fetch Article for it's salesprice
 Article__c art = [SELECT Id,Salesprice__c FROM Article__c WHERE Id = :retNew.Article__c  LIMIT 1]; 
 // Calculate the new total amount of this returnline, 
 // based on Salesprice * Total Quantity
 totalAmountNewReturn = art.Salesprice__c * retNew.Total_Quantity_Returned__c;
 // Update the Return record with this value as well.
 if(!Trigger.isDelete) {
  Return__c retTempToUpdate = [SELECT Id,Total_Amount_Returned_Calculated__c FROM Return__c WHERE Id = :retNew.Id  LIMIT 1][0];
  // Prevent infinite loop
  if(retTempToUpdate.Total_Amount_Returned_Calculated__c<>totalAmountNewReturn) {
   retTempToUpdate.Total_Amount_Returned_Calculated__c = totalAmountNewReturn;
   update retTempToUpdate;
 // Make calculation for the figures on Budget level
 Double budgetReturnAmountBefore = 0;
 Double budgetReturnQuantityBefore = 0; 
 budgetReturnAmountBefore = bud.Total_Amount_Returns__c; 
 budgetReturnQuantityBefore = bud.Total_Quantity_Returns__c;
 if(!Trigger.isDelete) {
  bud.Total_Amount_Returns__c = (budgetReturnAmountBefore - amOld) + totalAmountNewReturn;
  bud.Total_Quantity_Returns__c = (budgetReturnQuantityBefore - qtyOld) + retNew.Total_Quantity_Returned__c;
 } else {
  // In case of a delete the calculation is a bit different
  bud.Total_Amount_Returns__c = (budgetReturnAmountBefore - totalAmountNewReturn);
  bud.Total_Quantity_Returns__c = (budgetReturnQuantityBefore - retNew.Total_Quantity_Returned__c);
 update bud;

Any tips on the code are welcome too for a starting APEX developper:)