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
Sachin30Sachin30 

system.runas() with or without actual user insert

What is the difference between using a system.runas() method with a user without inserting the user or with inserting user. E.g:

User u = new User(...);
system.runAs(u){}

Vs

User u = new User(...);
insert u;
system.runAs(u){}

And which one is preferred as best practice?

TIA
VinayVinay (Salesforce Developers) 
Hi,

Generally, all Apex code runs in system mode, where the permissions and record sharing of the current user are not taken into account. The system method runAs enables you to write test methods that change the user context to an existing user or a new user so that the user’s record sharing is enforced. The runAs method doesn’t enforce user permissions or field-level permissions, only record sharing.

You can use runAs only in test methods. The original system context is started again after all runAs test methods complete.

The runAs method ignores user license limits. You can create new users with runAs even if your organization has no additional user licenses.


For example we have a class to create the campaign only if logged in user is marketing profile otherwise throwing error.

trigger campaignBeforeInser on Account (before insert) {
for(Campaign campaign: trigger.new){
if(userInfo.getProfileId == ‘marketing profile Id’){
campaign.currency = ‘USD’;
}
else{
campaign.addError(‘you are not authorized to create campaign’);
}
}
}


@isTest
private class CampaignTriggersTest{
private static testmethod void campaignTriggersTest(){
Profile prof = [select id from profile where name LIKE '%marketing%'];
User user = new User();
user.firstName = ‘test1’;
user.lastName = test2;
user.profileId = prof.id,username = ‘test@test.com’;
user.email = ‘test@test.com’;
insert user;
system.runAs(user){
Campaign campaign = new Campaign();
campaign.name = ‘laptop’;
insert campaign();
}
}
}

Hope above information was helpful.

Please mark as Best Answer so that it can help others in the future.

Thanks,
Vinay Kumar
Sachin30Sachin30
Thanks for the reply.

But the question is do we need to do an actual insert of user record or can we simple create an instance and use it in System.run() method? What is the difference between two and which one is preffered as best practice?
VinayVinay (Salesforce Developers) 
As mentioned in above example,  You need to insert user and runas in user mode 'system.runAs(u)' accordingly.

Note: You can only use runAs in test method.

Hope above information was helpful.

Thanks,
Vinay Kumar
Sachin30Sachin30
Thanks Vinay

But its not necessary to insert user object to get that System.runAs() working.

You can simply do:

User u = new User(...);
//no insert
system.runAs(u){}

My question is if thats fine not to insert user and just use the instance created to execute the test or do we need to insert user before we use it in system.runAs() and why? What is the difference in two approaches?

TIA
Felix van Hove 22Felix van Hove 22
Hello,

In all examples I have seen, Salesforce uses System.runAs(u) without inserting a new user in advance. Inserting the user in advance is redundant, because user insertion is one of the things System.runAs(u) is made for. One may runAs with the username marc.benioff@salesforce.com, look at the logs and the attempt to insert couldn't be more apparent. In fact, System.runAs() uses two counts of dmlStatements and dmlRows in case of an insert, and one of each in case the user already exists (and we used one count of each by doing the insert in advance). We don't save anything by taking the burden of user creation from runAs().

Felix