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
Pete WillisPete Willis 

57% code coverage on Milestone Complete

I am getting only 57% code coverage when running test on the standard complete milestone class.

User-added image

Is there a way to get 100% coverage on this.

Here is my test class for this.
 
@isTest ()
private class MilestoneTest {
static testMethod void TestCompleteMilestoneCase(){
    
    List<Account> acts = new List<Account>();
Account myAcc = new Account(Name='TestAct', phone='1001231234');
acts.add(myAcc);
Account busAcc = new Account(Name = 'TestForMS', phone='4567890999'); acts.add(busAcc);
insert acts;
    
Contact cont = new Contact(FirstName = 'Test', LastName = 'LastName', phone='4567890999',
 accountid = busAcc.id);
insert(cont);
Id contactId = cont.Id;
    
    Entitlement entl = new Entitlement(Name='TestEntitlement', AccountId=busAcc.Id);
insert entl;
String entlId;
if (entl != null)
entlId = entl.Id;

    
    List<Case> cases = new List<Case>{};
    if (entlId != null){
        Case c = new Case(Subject = 'Test Case with Entitlement ',
            EntitlementId = entlId, ContactId = contactId);
    cases.add(c);
}
if (cases.isEmpty()==false){
    insert cases;
    List<Id> caseIds = new List<Id>();
    for (Case cL : cases){
        caseIds.add(cL.Id);
  }
  milestoneUtils.completeMilestone(caseIds, 'First Response', System.now());
} }
static testMethod void testCompleteMilestoneViaCase(){
    
    List<Account> acts = new List<Account>();
	Account myAcc = new Account(Name='TestAct', phone='1001231234');
	acts.add(myAcc);
	Account busAcc = new Account(Name = 'TestForMS', phone='4567890999'); acts.add(busAcc);
	insert acts;
    
	Contact cont = new Contact(FirstName = 'Test', LastName = 'LastName', phone='4567890999',
 	accountid = busAcc.id);
	insert(cont);
	Id contactId = cont.Id;
    
  	Entitlement entl = new Entitlement(Name='TestEntitlement2', AccountId=busAcc.Id);
	insert entl;
	String entlId;
	if (entl != null)
	entlId = entl.Id;
    
    List<Case> cases = new List<Case>{};
    for(Integer i = 0; i < 1; i++){
        Case c = new Case(Subject = 'Test Case ' + i);
        cases.add(c);
        if (entlId != null){
            c = new Case(Subject = 'Test Case with Entitlement ' + i,
            EntitlementId = entlId);
            cases.add(c);
} }
    insert cases;
    
    List<CaseComment> ccs = new List<CaseComment>{};
    for(Case c : cases){
        CaseComment cc = new CaseComment(CommentBody='TestPublic',
                IsPublished=true, ParentId=c.Id);
        ccs.add(cc);
        cc = new CaseComment(CommentBody='TestPrivate',
                IsPublished=false, ParentId=c.Id);
        ccs.add(cc);
    }
    if (ccs.isEmpty()==false)
insert ccs;
    
    List<EmailMessage> emails = new List<EmailMessage>();
    for(Case c : cases){
        emails.add(new EmailMessage(parentId = c.id));
    }
    if(emails.isEmpty()==false)
        database.insert(emails);
for(Case c : cases){
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); String[] toAddr = new String[] {'user@company.com'};
    mail.setToAddresses(toAddr);
        mail.setSaveAsActivity(false);
        mail.setTargetObjectId(c.ContactId);
        mail.setWhatId(c.Id);
        mail.setHtmlBody('TestHTMLBody');
        mail.setPlainTextBody('TestTextBody');
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}
for(Case c : cases){
    c.Status = 'Closed';
}
update cases;
    List<Case> insertedCases = [SELECT Subject,
                   Description,
                   (SELECT IsPublished, CommentBody From CaseComments),
                   (SELECT TextBody, Subject, Incoming From EmailMessages)
                   FROM Case
                   WHERE Id IN :cases];
}
}

 
NagendraNagendra (Salesforce Developers) 
Hi Peter,

As you can see, the non-covered lines are the ones that are called when there is something in the cmsToUpdate list. So in your test code, you should make sure that there is something in the cmsToUpdate list, by inserting CaseMilestone records upfront that match the query parameters.

So after inserting the cases, create 1 or more CaseMileStone records for those cases, with the type 'First Response' and an empty completionDate.

Hope this helps.

Best Regards,
Nagendra.P
KONDA B 4KONDA B 4
Try the below code in MilestoneUtils  classs it will cover the test coverage.

public static void completeMilestone(List<Id> caseIds,String milestoneName, DateTime complDate) {  
        
        List<CaseMilestone> cmsToUpdate = [select Id, completionDate
                                           from CaseMilestone cm
                                           where caseId in :caseIds and cm.MilestoneType.Name=:milestoneName 
                                           and completionDate =  null limit 1];
        
        if (cmsToUpdate.isEmpty() == false||Test.isRunningTest()){
            for (CaseMilestone cm : cmsToUpdate){
                cm.completionDate = System.now();
            }
            update cmsToUpdate;
        }
    }