I'm writing a unit test to test code that is being used both by regular salesforce users and the site guest user. In order to do so, I'm using the System.runAs method. I was getting weird results, and narrowed it down to the fact that when using runAs guest user, I get different query results. Some setup code:

    Contact con2 = new Contact(FirstName = 'Test1', LastName = 'Test2',
                                MobilePhone='222-222-2222', Email='[email protected]');
    insert con2;

   Contact con_a = [SELECT Id from contact where email = '[email protected]' LIMIT 1];

This gives me a result.

However, when I do the following:

    User signUpFormUser = [SELECT Id, FirstName FROM User WHERE FirstName = 'SignUpForm' LIMIT 1];
        Contact con_s = [SELECT Id from contact where email = '[email protected]' LIMIT 1];


I get a List has no rows for assignment to SObject exception.

Why does this happen? How can I fix it?

1 Answer 1


When you use System.runAs(), you're establishing a different execution context, one where the record visibility for a specific user is implicitly enforced just like with Apex code that is running under the with sharing regime. In that new execution context you'll have the appropriate sharing rules and visibility for its running user applied to query results.

Presumably, in your organization, the Org-Wide Default for the Contact object is set to Private. Hence, con2 is owned by the original test-running user, and when the test code switches into the context of signUpFormUser, your test methods and with sharing Apex cannot see that Contact.

When you directly assign an Sobject to the result of a query (rather than a List<Sobject>) and the query returns no rows, you'll always get an exception. To avoid this, assign to a List and check the count returned.


You must log in to answer this question.

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