0

I'm implementing Communities and need to improve my org's security settings. I set Accounts to be private with a sharing rule of "Owner in all internal users" is shared with "All internal users". One of my unit tests fails when the trigger invokes a class that does:

private static Id ewn_new_id, ewn_used_id;
static {
   ewn_new_id = [SELECT Id FROM Account WHERE Name = 'Acme'].Id;
}

The error message is:

System.DmlException: Insert failed. First exception on row 0; first error:
CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, RMAtrig: execution of AfterInsert caused by:
System.QueryException: List has no rows for assignment to SObject

Class.RMA: line 8, column 1
Trigger.RMAtrig: line 6, column 1: []

The smoking gun is if I declare the RMA class "without sharing" the test passes. So, the only thing I can think of is unit tests don't run as an internal user?

  • It's failing based on your trigger. Can you post the relevant code for your trigger? – Nick Cook Jul 1 '14 at 0:24
  • You're right that a trigger is being run which, in turn, invokes Class.RMA line 8 (the SELECT statement). I tried to clarify the matter by editing the original post. – Scott Jul 1 '14 at 2:35
  • 2
    Are you inserting the test Account record in your test class? – Chetan Gupta Jul 1 '14 at 3:07
  • To elaborate on Chetan's comment, are you creating an 'Acme' Account in your test class? It sounds like ewn_new_id is not being assigned a value, which would make sense if there is no 'Acme' Account. – Nick Cook Jul 1 '14 at 3:36
  • This is an actual account in the org. This violates best practices, but I inherited this org and have my hands full keeping it running. – Scott Jul 1 '14 at 4:11
1

Replace below your code with below one to just try over coming the issue

ewn_new_id = [SELECT Id FROM Account WHERE Name = 'Acme'][0].Id;

But this way is not much better since it might cause an indexOutOfBound exception since we are purposely selecting the first record even without checking the query result for null. You can add little more code and fix this,

Id ewn_new_id;
List<Account> accnts = [SELECT Id FROM Account WHERE Name = 'Acme'];
if(!accnts.isEmpty()){
   ewn_new_id = accnts[0].Id;
}
  • Thanks for the idea. I can work around the problem by declaring the class "without sharing". Then ewn_new_id gets a correct value. – Scott Jul 1 '14 at 4:15
  • The point is, the value should load as null rather than throwing an exception. This recommendation is the best practice way to try to load a single record. – Adrian Larson Mar 27 '15 at 17:51
0

I was just wondering if you would try to remove your code from static block, as it might be getting invoked even before you might be creating your test record.

The best practice would be to create test data within test class invocation and use non-static method to retrieve record (to ensure that SOQL is fired only when needed).

Hope this helps

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.