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
glynnglynn 

Unit Test Help - first time writing Unit test

Hi,

 

I created my first ever trigger, see below. However, I've really struggled the last two days trying to Unit Test it.  I've failed miserably so far. I wonder can anyone here help me?  Here is my trigger:

 

 

trigger UserStatusBefore on User (before update) {
    
/**********************************************************************
*                                                                        
* This code fires *ONLY* when a user updates status on homepage. If user posts     *
* URL or file along with status, then FeedItemAfter trigger fires. FeedItemAfter   *
* trigger also fires when a user posts to another user's feed.                     *
*                                                                                  *
************************************************************************************/ 
    
    for (User f : trigger.new)
    {
        Datetime thisDT = System.now();
        String itemCreatedDate = thisDT.format('yyyy-MM-dd HH:mm:ss');
        String tiBod;       
           
        for (Id theId : trigger.oldMap.keySet())
           {
                User oldUsr=trigger.oldMap.get(theId);
                User newUsr=trigger.newMap.get(theId);
                String oldStatus=oldUsr.CurrentStatus;
                String newStatus=newUsr.CurrentStatus;
                String UserId1 = f.id;
                
                if (oldStatus != newStatus && null != newStatus)
                {
                    //UserProfileFeed up = [SELECT Id, Body, CommentCount, ContentData, ContentDescription, ContentFileName, ContentSize, ContentType, CreatedDate, InsertedByID, IsDeleted, LastModifiedDate, LikeCount, LinkUrl, ParentId, Title, Type FROM UserProfileFeed WITH UserId = :UserId1 LIMIT 1];
                    User u = [select id, name, email from user where id = :f.Id];                                    
                    tiBod = 'Posted Against: User Home Page' + '\n' + 'Message: ' + f.CurrentStatus + '\n' + 'Created by: ' + u.name + ' - ' + u.email + '\n' + 'Created On: ' + itemCreatedDate;
        
                    //Compile and send email message 
                    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                    String[] toAddresses = new String[] {System.Label.ChatterArchiveExternalEmailAddress};
                    mail.setToAddresses(toAddresses);
                    mail.setSubject('New UserStatus Update');
                    mail.setSaveAsActivity(false);
                    mail.setPlainTextBody(tiBod);
                    Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
                }
                else
                {    
                    //do nothing
                } 
           }          
    }    
}

 

Can someone show me what the Unit Test for this trigger looks like? thanks

 

Best Answer chosen by Admin (Salesforce Developers) 
SteveBowerSteveBower

 

I'm just typing this in and so there may be compile errors, etc. But this is a little cleaner.

 

 

trigger UserStatusBefore on User (before update) {
    
/*
*
* This code fires *ONLY* when a user updates status to a non-null
*
*/ 
    Datetime thisDT = System.now();
    String itemCreatedDate = thisDT.format('yyyy-MM-dd HH:mm:ss');
    String tiBod;  
    Messaging.SingleEmailMessage mail; 
    String[] toAddresses = new String[] {System.Label.ChatterArchiveExternalEmailAddress};
    List<Messaging.SingleEmailMessage> messagesToSend = new List<Messaging.SingleEmailMessage>();

 
    for (User f : trigger.new) {
        if (f.CurrentStatus != null && 
            f.CurrentStatus != trigger.oldMap.get(f.id).CurrentStatus
           ) {
             tiBod = 'Posted Against: User Home Page' + '\n' + 'Message: ' + f.CurrentStatus + '\n' + 'Created by: ' + f.name + ' - ' + f.email + '\n' + 'Created On: ' + itemCreatedDate;
             mail = new Messaging.SingleEmailMessage();
             mail.setToAddresses(toAddresses);
             mail.setSubject('New UserStatus Update');
             mail.setSaveAsActivity(false);
             mail.setPlainTextBody(tiBod);
             messagesToSend.add(mail);
        }
    }
    // Note: You really sound capture the results of your sendEmail call so you can make sure all the messages were properly sent.
    SendEmailResult[] res;
    if (!messagesToSend.isEmpty()) res = Messaging.sendEmail(messagesToSend);
    
}

Static testMethod void Test_UserStatusUpdate() { 
User x = new User(name="x", CurrentStatus="Peanuts", email="spam@spam.com", etc....); 
insert x; x.CurrentStatus="Popcorn"; update x; // Check that the update was successful. system.assertEquals('Popcorn',[select currentStatus from User where id=:x.id].currentStatus); }

 

The problem with the test case is that it doesn't actually check that the e-mail message was properly sent.  However, I don't believe there is a simple way to do that.  (I think arequest to come up with a way to do *real* testing of sendmail is on the idea exchange somewhere)  

 

So, in the meantime, all you're really trying to do with your test coverage is make sure that the code gets executed, and that the stuff you can check is actually checked.

 

You *could* write code in your class to check the status of the sendEmail call, and check to see if any of the results are not successful.  If so, you could throw an exception.  Then you could write your test method to try/catch exceptions.  Then create a user with a null e-mail address, try to update a status for that user, and then check that you've caught an exception in the test.  But, how far do you want to go to test the SendMail mechanism.  

 

Hope it helps, Steve.

 

 

 

 

 

All Answers

SteveBowerSteveBower

 

I'm just typing this in and so there may be compile errors, etc. But this is a little cleaner.

 

 

trigger UserStatusBefore on User (before update) {
    
/*
*
* This code fires *ONLY* when a user updates status to a non-null
*
*/ 
    Datetime thisDT = System.now();
    String itemCreatedDate = thisDT.format('yyyy-MM-dd HH:mm:ss');
    String tiBod;  
    Messaging.SingleEmailMessage mail; 
    String[] toAddresses = new String[] {System.Label.ChatterArchiveExternalEmailAddress};
    List<Messaging.SingleEmailMessage> messagesToSend = new List<Messaging.SingleEmailMessage>();

 
    for (User f : trigger.new) {
        if (f.CurrentStatus != null && 
            f.CurrentStatus != trigger.oldMap.get(f.id).CurrentStatus
           ) {
             tiBod = 'Posted Against: User Home Page' + '\n' + 'Message: ' + f.CurrentStatus + '\n' + 'Created by: ' + f.name + ' - ' + f.email + '\n' + 'Created On: ' + itemCreatedDate;
             mail = new Messaging.SingleEmailMessage();
             mail.setToAddresses(toAddresses);
             mail.setSubject('New UserStatus Update');
             mail.setSaveAsActivity(false);
             mail.setPlainTextBody(tiBod);
             messagesToSend.add(mail);
        }
    }
    // Note: You really sound capture the results of your sendEmail call so you can make sure all the messages were properly sent.
    SendEmailResult[] res;
    if (!messagesToSend.isEmpty()) res = Messaging.sendEmail(messagesToSend);
    
}

Static testMethod void Test_UserStatusUpdate() { 
User x = new User(name="x", CurrentStatus="Peanuts", email="spam@spam.com", etc....); 
insert x; x.CurrentStatus="Popcorn"; update x; // Check that the update was successful. system.assertEquals('Popcorn',[select currentStatus from User where id=:x.id].currentStatus); }

 

The problem with the test case is that it doesn't actually check that the e-mail message was properly sent.  However, I don't believe there is a simple way to do that.  (I think arequest to come up with a way to do *real* testing of sendmail is on the idea exchange somewhere)  

 

So, in the meantime, all you're really trying to do with your test coverage is make sure that the code gets executed, and that the stuff you can check is actually checked.

 

You *could* write code in your class to check the status of the sendEmail call, and check to see if any of the results are not successful.  If so, you could throw an exception.  Then you could write your test method to try/catch exceptions.  Then create a user with a null e-mail address, try to update a status for that user, and then check that you've caught an exception in the test.  But, how far do you want to go to test the SendMail mechanism.  

 

Hope it helps, Steve.

 

 

 

 

 

This was selected as the best answer
glynnglynn

thanks Steve