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?

7
  • It's failing based on your trigger. Can you post the relevant code for your trigger?
    – Nick C
    Commented Jul 1, 2014 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
    Commented Jul 1, 2014 at 2:35
  • 2
    Are you inserting the test Account record in your test class? Commented Jul 1, 2014 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 C
    Commented Jul 1, 2014 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
    Commented Jul 1, 2014 at 4:11

2 Answers 2

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;
}
2
  • 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
    Commented Jul 1, 2014 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
    Commented Mar 27, 2015 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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .