You need to sign in to do that
Don't have an account?
Holly Havelka 10
Test Class for Synchronizing Portal Users with Contact Record Data
Hello all,
I am struggling to write a Test Class for the following trigger and static class that synchronizes portal users with contact record data:
I am getting no code coverage when I runt the test. Can someone help point me to what I am missing?
Thanks in advance for any help.
I am struggling to write a Test Class for the following trigger and static class that synchronizes portal users with contact record data:
trigger UpdateContactFromPortalUser on User (after update) { //We only want to run on the single item that the user edited if (Trigger.new.size()==1) { User u =_ Trigger.new[0]; //And only if it's a portal user if (u.ContactId!=null) { UpdateContactFromPortalUser.updateContacts(u.Id); } } }
global class UpdateContactFromPortalUser { @future public static void updateContacts(String userId) { User u = [select ContactId,Email,FirstName,LastName,Title from User where Id=:userId]; if (u!=null && u.ContactId!=null) { Contact c = new Contact(Id=u.ContactId,Email=u.Email,FirstName=u.FirstName,LastName=u.LastName,Title=u.Title); update c; } } }Here is my test class code:
@isTest private class UpdateContactFromPortalUserTest { static testMethod void testUpdateContacts() { Test.startTest(); User u = [select Id,ContactId,FirstName from User where ContactId<>'' limit 1]; u.FirstName='Bar'; update u; Test.stopTest(); Contact c = [select FirstName from Contact where Id=:u.ContactId]; System.assertEquals(c.FirstName,u.FirstName); } }
I am getting no code coverage when I runt the test. Can someone help point me to what I am missing?
Thanks in advance for any help.
First, your trigger should be bulkified to process any number of objects and not just one. Running on a single item is against Salesforce best practices and can get you in trouble with Salesforce resource limits.
Second, the trigger objects have all of the field values that you are requerying in Lines 4-6 of UpdateContactFromPortalUser.updateContacts....so that query is unnecessary and should be removed.
Third, best practices for unit tests are to insert your own data. You haven't inserted a Contact in your test method, therefore there is no Contact to update. If you were to use an existing user (also against best practices), you would be using a ContactId that won't exist in the test context. I've corrected a few of the issues below in the code example, I hope it helps. The code hasn't been run/tested, but should give you an idea of how you can solve your issue.
All Answers
Your trigger is using protal user and the triggerhandler is using future annotation. This is too much to complicate the test class without having seeAllData=true. Intead of that I can suggest you only to get some code coverage without using seeAllData=true
Thanks,
Prosenjit
First, your trigger should be bulkified to process any number of objects and not just one. Running on a single item is against Salesforce best practices and can get you in trouble with Salesforce resource limits.
Second, the trigger objects have all of the field values that you are requerying in Lines 4-6 of UpdateContactFromPortalUser.updateContacts....so that query is unnecessary and should be removed.
Third, best practices for unit tests are to insert your own data. You haven't inserted a Contact in your test method, therefore there is no Contact to update. If you were to use an existing user (also against best practices), you would be using a ContactId that won't exist in the test context. I've corrected a few of the issues below in the code example, I hope it helps. The code hasn't been run/tested, but should give you an idea of how you can solve your issue.
Any thoughts on this issue?
You can use system.runAs() method to run the test class through portal user. You have to profile with name portal profile like portal community user and create a user corresponding to that profile and then after use system.runAs() method to execute your logic inside that.
Thanks
Object/sObjects cannot be passed in as parameters in @future context.
If you remove the @future, then your original code will work.
(Signature = public static void updateContacts(List<User> users))
If you must use the @future context, then you can only pass in a primitive data type and would need to do something different.
Sample code below: