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
Ron HessRon Hess 

Validation rules can see org data even when called from a test method which cannot

I've reported a bug to the partner portal, case 08197046

 

I'd like to understand if anyone else has reported this issue or worked around it.

 

we have a simple rule to identify duplicates on the Name field.

 

AND(OR(ISNEW(),ISCHANGED(Name)), VLOOKUP( $ObjectType.Supplier__c.Fields.Name , $ObjectType.Supplier__c.Fields.Name ,Name)<>NULL)

 

 

and a simple testmethod 

 

System.assertEquals( 0, [ select id from Supplier__c ].size() );
Supplier__c supplierObj = new Supplier__c();
supplierObj.Name= 'Test Supplier';    
insert supplierObj;

 

My API setting is 25.0, and the assert passes, since no data is visible to my test method.

 

now, i run my test method and it fails on the insert statement ( yes the database has a Test Supplier )

 

 

18:05:03.386 (5386958000)|SOQL_EXECUTE_BEGIN|[64]|Aggregations:0|select id from Supplier__c
18:05:03.388 (5388301000)|SOQL_EXECUTE_END|[64]|Rows:0
18:05:03.388 (5388663000)|DML_BEGIN|[67]|Op:Insert|Type:Supplier__c|Rows:1
18:05:03.400 (5400613000)|CODE_UNIT_STARTED|[EXTERNAL]|Validation:Supplier:new
18:05:03.400 (5400628000)|VALIDATION_RULE|03dE00000000EbW|Unique_Name
18:05:03.400 (5400914000)|VALIDATION_FORMULA|AND(OR(ISNEW(),ISCHANGED(Name)), VLOOKUP( $ObjectType.Supplier__c.Fields.Name  ,  $ObjectType.Supplier__c.Fields.Name ,Name)<>NULL)|Name=Test Supplier , $ObjectType.Supplier__c.Fields.Name=Supplier__c.Name
18:05:03.400 (5400929000)|VALIDATION_FAIL
18:05:03.404 (5404672000)|CODE_UNIT_FINISHED|Validation:Supplier:new
18:05:03.405 (5405933000)|DML_END|[67]
18:05:03.408 (5408566000)|VF_PAGE_MESSAGE|This Supplier already exists
18:05:03.408 (5408686000)|EXCEPTION_THROWN|[67]|System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, This Supplier already exists: [Name]
18:05:03.409 (5409633000)|FATAL_ERROR|System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, This Supplier already exists: [Name]

 

I can conclude that VLOOKUP() can see data even if called from a test method that cannot see data.

 

This makes validation rules look like a serious hazard when writing test methods, how could i know what data is already in the org ? How can i protect my test methods from data that exists ?

 

I turned off this validation rule, and sure enough the test method behaves as expected.

 

thanks for any ideas.

 

kibitzerkibitzer

Is there a change in behavior between Summer 12 and Winter 13? It would be helpful to know if this is a preexisting situation or a breaking change (and I suspect Salesforce would like to know that as well).


Dan

 

RoyGiladRoyGilad

Hi Ron,

I'm not familiar with the problem you presented, but I have implemented a work-around without knowing your way.

 

Create a new custom "Name" field which doesn't have to be on the layout. Define this field as Unique. Create a workflow that copy the name of the object from the standard name field to the new field you've just created. 
When someone creates the object the name is being copied to the new custom field, in case it's duplicate the system present an error message (since the new field is defined as unique) that it's a duplicate.

 

I hope that helps,

Roy

Ron HessRon Hess

This is on Summer 12, i will be relieved if it's addressed in Winter 13.

Ron HessRon Hess

This is a good idea, and may become a workaround, but the underlying issue is a serious problem as a customer can write a validation rule and defeat my efforts to craft exelent test methods that always work.