Recently we came across this strange behavior in prod vs sandbox deployment. As part of mock deployment, we deployed the exact same class(es) to a recently created sandbox and everything was fine. Now, when we tried deploying to production, we got some test class failure.

The test class is creating test records and testing the methods of a class. The specific issue was due to Opportunity record insertion. Upon checking it was due to a process builder flow failure. We debugged further and found out that the process builder will be called only for a record type and in no way this test class was inserting that record with the record type, since we were using system.runAs(), as an user whose record type is different.

More interestingly, the test user is a Community Plus User, who doesn't even have object (Opportunity) permission!! Wondering how this was working in dev sandbox and other sandboxes? We fixed it by removing the object insertion in the code, since it wasn't necessary for our use case (blame the person who wrote it).

My question is, does apex run in system mode if the runAs() user doesn't have object permission? I would have expected this to throw exception rather than running in system mode.


2 Answers 2


According to the documentation, System.runAs with user as a parameter, does not enforce provided user permissions or field-level permissions, only record sharing.

Documentation about that is here


runAs() only enforces sharing of records.Try this:

private class RunasDemo {
//Standard user from org: 0051v000006F9z
//User without Account CRUD access: 0051v000006F9zD
private static testMethod void doDemo() {
    Account a = new Account();
    a.Name = 'Mine';
    insert a;
    System.Debug('## Count as admin '+[SELECT count() FROM Account]);

    User normalUser = [SELECT Id FROM User WHERE Id ='0051v000006F9z3'];
    System.runAs(normalUser) {
        System.Debug('## Count as normal user '+[SELECT count() FROM Account]);
    User noAccessUser = [SELECT Id FROM User WHERE Id ='0051v000006F9zD'];
    System.runAs(noAccessUser) {
        System.Debug('## Count as no access user '+[SELECT count() FROM Account]);


  • ugh, hardcoding of Id's is quite bad..
    – Raul
    Jul 8, 2019 at 13:12
  • 1
    @Raul - this is example to demonstrate how runAs() work. Not a actual code! Its shows even if a user doesn't have access to account object he can still query to see if sharing is applicable Jul 9, 2019 at 10:58

You must log in to answer this question.

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