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
DevNVDevNV 

Testing Apex Managed Sharing Recalculations - documentation not working

Hi all, 

 

I'm working on the sharing recalculation coding and have tried to implement the example code in the Apex Code documentation (http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_bulk_sharing_recalc.htm).  I'm getting errors when saving the test code as documented at the bottom.  The calls to start() and execute() are not saving with the error that the method does not exist. 

 

Has anyone else figured it out?  

 

Cheers,

Niki

Best Answer chosen by Admin (Salesforce Developers) 
joshbirkjoshbirk

OK, sorry for the delay.  The documentation did have a few issues and the internal team is getting those corrections in.

 

They also sent along this corrected version:

 

@isTest
private class JobSharingTester {
   
   // Test for the JobSharingRecalc class    
    static testMethod void testApexSharing(){
       // Instantiate the class implementing the Database.Batchable interface.     
        JobSharingRecalc recalc = new JobSharingRecalc();
        
        // Select users for the test.
        List<User> users = [SELECT Id FROM User WHERE IsActive = true LIMIT 2];
        ID User1Id = users[0].Id;
        ID User2Id = users[1].Id;
        
        // Insert some test job records.                 
        List<Job__c> testJobs = new List<Job__c>();
        for (Integer i=0;i<5;i++) {
            Job__c j = new Job__c();
            j.Name = 'Test Job ' + i;
            j.Recruiter__c = User1Id;
            j.Hiring_Manager__c = User2Id;
            testJobs.add(j);
        }
        insert testJobs;
        
        Test.startTest();
        
        // Invoke the Batch class.
        String jobId = Database.executeBatch(recalc);
        
        Test.stopTest();
        
        // Get the Apex job and verify there are no errors.
        AsyncApexJob aaj = [Select JobType, TotalJobItems, JobItemsProcessed, Status, 
                            CompletedDate, CreatedDate, NumberOfErrors 
                            from AsyncApexJob where Id = :jobId];
        System.assertEquals(0, aaj.NumberOfErrors);
         
        // This query returns jobs and related sharing records that were inserted       
        // by the batch job's execute method.     
        List<Job__c> jobs = [SELECT Id, Hiring_Manager__c, Recruiter__c, 
            (SELECT Id, ParentId, UserOrGroupId, AccessLevel, RowCause FROM Shares 
            WHERE (RowCause = :Schema.Job__Share.rowCause.Recruiter__c OR 
            RowCause = :Schema.Job__Share.rowCause.Hiring_Manager__c))
            FROM Job__c];       

        // Validate that Apex managed sharing exists on jobs.      
        for(Job__c job : jobs){
            // Two Apex managed sharing records should exist for each job
            // when using the Private org-wide default. 
            System.assert(job.Shares.size() == 2);
            
            for(Job__Share jobShr : job.Shares){
               // Test the sharing record for hiring manager on job.              
                if(jobShr.RowCause == Schema.Job__Share.RowCause.Hiring_Manager__c){
                    System.assertEquals(jobShr.UserOrGroupId,job.Hiring_Manager__c);
                    System.assertEquals(jobShr.AccessLevel,'Read');
                }
                // Test the sharing record for recruiter on job. 
                else if(jobShr.RowCause == Schema.Job__Share.RowCause.Recruiter__c){
                    System.assertEquals(jobShr.UserOrGroupId,job.Recruiter__c);
                    System.assertEquals(jobShr.AccessLevel,'Edit');
                }
            }
       }       
    }
}

 

 

Updated the code with a new example from the documentation team - 12/12/2011

 

And mentioned that:

"It calls the batch job through the Database.executeBatch() method, which is the recommended way.
 
Note that the customer could make his code work with a quick fix by just declaring the Database.BatchableContext variable and passing it uninitialized to the 3 methods (start, execute, finish) but this is not the recommended way."

 

Hope that helps.

All Answers

joshbirkjoshbirk

Are you using the samples out of the box?  Same data setup, etc.?  I can try them out on this and see...

DevNVDevNV

It's pretty much the same, although I'm using the jobs object called SFDC_Job__c rather than just Job__c.  I adjusted the SOQL for my object but otherwise the structure is the same.  The problem is in saving the test method as it is in the documentation - besides the typo on one the select statement not having [ ]'s around it, it is giving errors on calling the Start and Execute methods directly.  Any thoughts would be appreciated.

joshbirkjoshbirk

Sorry - brief delay trying to get this enabled on my own end...

joshbirkjoshbirk

Just a quick ping that some internal folks are going to take the sample for a test drive.  Sorry again for the delays, there's holidays and deadlines abound - which often don't mix...

joshbirkjoshbirk

OK, sorry for the delay.  The documentation did have a few issues and the internal team is getting those corrections in.

 

They also sent along this corrected version:

 

@isTest
private class JobSharingTester {
   
   // Test for the JobSharingRecalc class    
    static testMethod void testApexSharing(){
       // Instantiate the class implementing the Database.Batchable interface.     
        JobSharingRecalc recalc = new JobSharingRecalc();
        
        // Select users for the test.
        List<User> users = [SELECT Id FROM User WHERE IsActive = true LIMIT 2];
        ID User1Id = users[0].Id;
        ID User2Id = users[1].Id;
        
        // Insert some test job records.                 
        List<Job__c> testJobs = new List<Job__c>();
        for (Integer i=0;i<5;i++) {
            Job__c j = new Job__c();
            j.Name = 'Test Job ' + i;
            j.Recruiter__c = User1Id;
            j.Hiring_Manager__c = User2Id;
            testJobs.add(j);
        }
        insert testJobs;
        
        Test.startTest();
        
        // Invoke the Batch class.
        String jobId = Database.executeBatch(recalc);
        
        Test.stopTest();
        
        // Get the Apex job and verify there are no errors.
        AsyncApexJob aaj = [Select JobType, TotalJobItems, JobItemsProcessed, Status, 
                            CompletedDate, CreatedDate, NumberOfErrors 
                            from AsyncApexJob where Id = :jobId];
        System.assertEquals(0, aaj.NumberOfErrors);
         
        // This query returns jobs and related sharing records that were inserted       
        // by the batch job's execute method.     
        List<Job__c> jobs = [SELECT Id, Hiring_Manager__c, Recruiter__c, 
            (SELECT Id, ParentId, UserOrGroupId, AccessLevel, RowCause FROM Shares 
            WHERE (RowCause = :Schema.Job__Share.rowCause.Recruiter__c OR 
            RowCause = :Schema.Job__Share.rowCause.Hiring_Manager__c))
            FROM Job__c];       

        // Validate that Apex managed sharing exists on jobs.      
        for(Job__c job : jobs){
            // Two Apex managed sharing records should exist for each job
            // when using the Private org-wide default. 
            System.assert(job.Shares.size() == 2);
            
            for(Job__Share jobShr : job.Shares){
               // Test the sharing record for hiring manager on job.              
                if(jobShr.RowCause == Schema.Job__Share.RowCause.Hiring_Manager__c){
                    System.assertEquals(jobShr.UserOrGroupId,job.Hiring_Manager__c);
                    System.assertEquals(jobShr.AccessLevel,'Read');
                }
                // Test the sharing record for recruiter on job. 
                else if(jobShr.RowCause == Schema.Job__Share.RowCause.Recruiter__c){
                    System.assertEquals(jobShr.UserOrGroupId,job.Recruiter__c);
                    System.assertEquals(jobShr.AccessLevel,'Edit');
                }
            }
       }       
    }
}

 

 

Updated the code with a new example from the documentation team - 12/12/2011

 

And mentioned that:

"It calls the batch job through the Database.executeBatch() method, which is the recommended way.
 
Note that the customer could make his code work with a quick fix by just declaring the Database.BatchableContext variable and passing it uninitialized to the 3 methods (start, execute, finish) but this is not the recommended way."

 

Hope that helps.

This was selected as the best answer
DevNVDevNV

Great, this seems to work now in my environment as well.  Thanks for fixing it up!