0

I have a apex method which retrieves url parameters and perform SOQL and then DML operation. Here's the apex method,

public void updateObjRecord(){

    try{
        String objId = System.currentPageReference().getParameters().get('lid');        
        object__c objToUpdate = [Select Id, Name, Participated__c From object__c Where Id = :objId]; 

        if (objToUpdate != null){
            objToUpdate.Participated__c = true;            
            upsert objToUpdate;
        }
        this.showSuccess = true;
    }catch(exception ex){
        System.debug('Error connecting to the Lead: '+ex.getMessage());
        this.errorMsg = 'There are some issues updating the Obj. Please use the form instead!';
        this.showError = true;
    }

}

I have written a test method to cover the above code and it works fine. However I wanted to write another test method for another user with different profile to execute the same code system.runas(). While it works well for normal method, it gives me List has no rows error on above leadToUpdate SOQL for this different user. Here is my test method,

@isTest
static void processObjTestMethod_withCounselor(){

    String uniqueUserName = 'user' + DateTime.now().getTime() + '@dom.com';
    Profile p = [SELECT Id FROM Profile WHERE Name='Counsellor'];
    User u = new User(Alias = 'standt', Email='counsellor@cd.com',
        EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
        LocaleSidKey='en_US', ProfileId = p.Id,
        TimeZoneSidKey='America/Los_Angeles',
        UserName=uniqueUserName);

        System.runAs(u) {

            Test.startTest();

            Object__c ld = [Select Id, Name, Mobile__c, Email__c, Participated__c from Object__c LIMIT 1];

            ControllerClass ctrl = new ControllerClass();
            PageReference pageRef = Page.vfPage;
            test.setCurrentPageReference(pageRef);

            pageRef.getParameters().put('lid',ld.Id);            
            ctrl.updateLeadRecord();
            Test.stopTest();
        }


        Object__c objRec = [Select Id, Name, Participated__c From Object__c LIMIT 1];
        System.debug('objRec ::'+objRec.Participated__c);
        System.assertEquals(objRec.Participated__c, true);

}

Please note that I have a testsetup method to create Object__c record at the first place. Here's the setupdata method,

@testSetup static void setupTestData() {

    Object__c ld = new Object__c();
    ld.Email__c = 'test@test.com';
    ld.Mobile__c = '123456789';
    ld.First_Name__c = 'fName';
    ld.Last_Name__c = 'lName';

    insert ld;

}

Where this could go wrong?

2
  • [Deleted my prior comment] - Is the Object__c org wide sharing setting marked as Private? If so, the records created in testSetup are likely not visible to the running user. How are the records from testSetup being shared to this user?
    – Mark Pond
    Feb 26 '19 at 18:58
  • Yes it's private. I didn't do anything specifically to share the record within testsetup. its just a basic method without even a test data factory. I have added that in to the original post Feb 26 '19 at 19:12
1

Your @testSetup method is running with the context user as whoever is executing the test case. Most likely, that's you. That user is the owner of the Object__c records that get created.

When you switch into the context of the user u, you're establishing a different visibility regime, dictated by your org's sharing settings, role hierarchy, profile permissions, and so forth. It's also influenced by whether your classes are running in a with sharing or without sharing regime.

If your Org-Wide Default is Private, and your classes are running with sharing, the result you are seeing is the expected outcome because sharing is being enforced and user u doesn't have permission to see records owned by the test-running user.

2
  • Thank you! this works well for real records. Basically updateObjRecord is an action function of a VF page. So this Counselor user can access any Object__c record regardless of who created it. Also it should be alright if I create a Object__c record within system.runas(u) context as the owner of the record will be 'u' right? Feb 27 '19 at 3:07
  • @LMudiyanse Yes, if you do not specify an OwnerId, the owner of the record is the user who creates it.
    – David Reed
    Feb 27 '19 at 3:08

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.