+ Start a Discussion
Ewa FrystEwa Fryst 

help with Apex class test

Hello,
I have the following trigger on Case that defaults entitlements on Case record. I need to have 75% code coverage but i only managed to get 57% (found it on internet). Could anyone help me and amend the below test class to achieve the 75%?
Also, i don't really need the trigger to look at Contacts, only at Account level so that could be removed from the trigger if it is easier with writing the test class.
I would appreciate your help.
EwaUser-added image

The TRIGGER
trigger DefaultEntitlement on Case (Before Insert, Before Update) {
    Set<Id> contactIds = new Set<Id>();
    Set<Id> acctIds = new Set<Id>();
    for (Case c : Trigger.new) {
        contactIds.add(c.ContactId);
        acctIds.add(c.AccountId);
    }
    
    List <Entitlement> entls = [Select e.StartDate, e.Id, e.EndDate, 
                e.AccountId, e.AssetId
                From Entitlement e
                Where e.AccountId in :acctIds And e.EndDate >= Today 
                And e.StartDate <= Today];
        if(entls.isEmpty()==false){
            for(Case c : Trigger.new){
                if(c.EntitlementId == null && c.AccountId != null){
                    for(Entitlement e:entls){
                        if(e.AccountId==c.AccountId){
                            c.EntitlementId = e.Id;
                            if(c.AssetId==null && e.AssetId!=null)
                                c.AssetId=e.AssetId;
                            break;
    
    
                    }
                } 
            }
        } 
    } else{
        List <EntitlementContact> entlContacts = 
                [Select e.EntitlementId,e.ContactId,e.Entitlement.AssetId 
                From EntitlementContact e
                Where e.ContactId in :contactIds
                And e.Entitlement.EndDate >= Today 
                And e.Entitlement.StartDate <= Today];
    if(entlContacts.isEmpty()==false){
        for(Case c : Trigger.new){
            if(c.EntitlementId == null && c.ContactId != null){
                for(EntitlementContact ec:entlContacts){
                    if(ec.ContactId==c.ContactId){
                        c.EntitlementId = ec.EntitlementId;
                        if(c.AssetId==null && ec.Entitlement.AssetId!=null)
                            c.AssetId=ec.Entitlement.AssetId;
                        break;
                        }
                    } 
                }
            } 
        }
    }
}


THE TEST CLASS

@isTest
private class DefaultEntitlementTest {

    static testMethod void myUnitTest() {
        Account acc = new Account(Name='testacc');
        insert acc;

        Contact con = new Contact(FirstName='john', LastName='doe', Email='john@doe.com', AccountId=acc.Id);
        insert con;

        Asset ass = new Asset(AccountId=acc.Id,ContactId=con.Id, Name='testing');
        insert ass;

        Entitlement ent = new Entitlement(Name='Testing', AccountId=acc.Id, StartDate=Date.valueof(System.now().addDays(-2)), EndDate=Date.valueof(System.now().addYears(2)), AssetId=ass.Id);
        insert ent;

        Entitlement ent2 = new Entitlement(Name='test2', AccountId=acc.Id, StartDate=Date.valueof(System.now().addDays(-10)), EndDate=Date.valueof(System.now().addYears(3)));
        insert ent2;

        EntitlementContact ec = new EntitlementContact(EntitlementId=ent.Id, ContactId=con.Id);
        insert ec;

        List<Case> listC = new list<Case>();
        List<Id> newCaseIds = new List<Id>();
        for(Integer i=0;i<20;i++){
            Case c = new Case(ContactId=con.Id, AccountId=con.AccountId, Subject='Test Subject'+i, Origin='Webform_B2B');

            listC.add(c);
        }
        test.startTest();
        insert listC;

        test.stopTest();
        for (Case caseObj:listC) {
            newCaseIds.add(caseObj.Id);
        }

        List<Case> entls = [Select EntitlementId, AssetId, ContactId, AccountId From Case Where Id in :newCaseIds];

        for (Case caseObj:entls) {

            System.debug(caseObj.Id + ' here are the values ' + caseObj.EntitlementId + ' and here ent.Id ' + ent.Id);

            System.assertEquals(caseObj.EntitlementId, ent.Id);

        }
        Contact con2 = new Contact(FirstName = 'Jane',
        LastName = 'Doe',
        Email='jane@doe.com');

        insert con2;
        Entitlement ent3 = new Entitlement(Name='Testing', AccountId=acc.Id, StartDate=Date.valueof(System.now().addDays(2)), EndDate=Date.valueof(System.now().addYears(2)), AssetId=ass.Id);
        insert ent3;

        EntitlementContact ec2 = new EntitlementContact(EntitlementId=ent3.Id, ContactId=con2.Id);
        insert ec2;
        Case c1 = new Case(ContactId=con2.Id, AccountId=con.AccountId, Subject='Test Subject', Origin='Webform_B2B');
        insert c1;
        update c1;
    }
}
Best Answer chosen by Ewa Fryst
Andrew GAndrew G
Your coverage will be down because you have an IF...ELSE ... statement in your trigger,

Your Single Test Method only tests one of the branches.

Create a second test the fulfills the entry requirement for the ELSE branch.

I would also look at using @TestSetup
something like:
 
@isTest
private class DefaultEntitlementTest {
@testSetup 
    static void setup() {
        Account acc = new Account(Name='testacc');
        insert acc;

        Contact con = new Contact(FirstName='john', LastName='doe', Email='john@doe.com', AccountId=acc.Id);
        insert con;

        Asset ass = new Asset(AccountId=acc.Id,ContactId=con.Id, Name='testing');
        insert ass;

        Entitlement ent = new Entitlement(Name='Testing', AccountId=acc.Id, StartDate=Date.valueof(System.now().addDays(-2)), EndDate=Date.valueof(System.now().addYears(2)), AssetId=ass.Id);
        insert ent;

        Entitlement ent2 = new Entitlement(Name='test2', AccountId=acc.Id, StartDate=Date.valueof(System.now().addDays(-10)), EndDate=Date.valueof(System.now().addYears(3)));
        insert ent2;
    }

 static testMethod void myUnitTest_1() {
        Contact con - [SELECT Id, AccountId FROM Contact WHERE Email ='john@doe.com' LIMIT 1];
        List<Case> listC = new list<Case>();
        List<Id> newCaseIds = new List<Id>();
        for(Integer i=0;i<20;i++){
            Case c = new Case(ContactId=con.Id, AccountId=con.AccountId, Subject='Test Subject'+i, Origin='Webform_B2B');

            listC.add(c);
        }
        test.startTest();
        insert listC;

        test.stopTest();
       //do some asserts

  }  //end test one

 static testMethod void myUnitTest_2() {
//some other test for the other branch
}
      

regards
Andrew
 

All Answers

Andrew GAndrew G
Your coverage will be down because you have an IF...ELSE ... statement in your trigger,

Your Single Test Method only tests one of the branches.

Create a second test the fulfills the entry requirement for the ELSE branch.

I would also look at using @TestSetup
something like:
 
@isTest
private class DefaultEntitlementTest {
@testSetup 
    static void setup() {
        Account acc = new Account(Name='testacc');
        insert acc;

        Contact con = new Contact(FirstName='john', LastName='doe', Email='john@doe.com', AccountId=acc.Id);
        insert con;

        Asset ass = new Asset(AccountId=acc.Id,ContactId=con.Id, Name='testing');
        insert ass;

        Entitlement ent = new Entitlement(Name='Testing', AccountId=acc.Id, StartDate=Date.valueof(System.now().addDays(-2)), EndDate=Date.valueof(System.now().addYears(2)), AssetId=ass.Id);
        insert ent;

        Entitlement ent2 = new Entitlement(Name='test2', AccountId=acc.Id, StartDate=Date.valueof(System.now().addDays(-10)), EndDate=Date.valueof(System.now().addYears(3)));
        insert ent2;
    }

 static testMethod void myUnitTest_1() {
        Contact con - [SELECT Id, AccountId FROM Contact WHERE Email ='john@doe.com' LIMIT 1];
        List<Case> listC = new list<Case>();
        List<Id> newCaseIds = new List<Id>();
        for(Integer i=0;i<20;i++){
            Case c = new Case(ContactId=con.Id, AccountId=con.AccountId, Subject='Test Subject'+i, Origin='Webform_B2B');

            listC.add(c);
        }
        test.startTest();
        insert listC;

        test.stopTest();
       //do some asserts

  }  //end test one

 static testMethod void myUnitTest_2() {
//some other test for the other branch
}
      

regards
Andrew
 
This was selected as the best answer
Ewa FrystEwa Fryst
Hi Andrew,
Thanks for your response.
I'm not a developper so not sure how to change the test class with the ELSE branch. Or, shall i just use yours instead?
I tried but i got the error. Would you be able to correct it?

User-added image
Many thanks
Ewa
Andrew GAndrew G
Hi Ewa

There is a typo in the line - notice the dash which should be an equals

Contact con = [SELECT Id, AccountId FROM Contact WHERE Email ='john@doe.com' LIMIT 1];

as for how to do the test class, where there is a branch like IF..ELSE.. I find it better to produce 2 x test methods as shown in the rough example above.

you could simply use the two methods below - they should go close to coverng the trigger.
 
@IsTest
    static void myUnitTest_one() {
        Account acc = new Account(Name='testacc');
        insert acc;

        Contact con = new Contact(FirstName='john', LastName='doe', Email='john@doe.com', AccountId=acc.Id);
        insert con;

        Asset ass = new Asset(AccountId=acc.Id,ContactId=con.Id, Name='testing');
        insert ass;

        Entitlement ent = new Entitlement(Name='Testing', AccountId=acc.Id, StartDate=Date.valueOf(System.now().addDays(-2)), EndDate=Date.valueOf(System.now().addYears(2)), AssetId=ass.Id);
        insert ent;

        List<Case> listC = new List<Case>();
        List<Id> newCaseIds = new List<Id>();
        for(Integer i=0;i<20;i++){
            Case c = new Case(ContactId=con.Id, AccountId=con.AccountId, Subject='Test Subject'+i, Origin='Webform_B2B');
            listC.add(c);
        }

        Test.startTest();
        insert listC;
        Test.stopTest();

        for (Case caseObj:listC) {
            newCaseIds.add(caseObj.Id);
        }

        List<Case> entls = [SELECT EntitlementId, AssetId, ContactId, AccountId FROM Case WHERE Id IN :newCaseIds];

        for (Case caseObj:entls) {
            System.debug(caseObj.Id + ' here are the values ' + caseObj.EntitlementId + ' and here ent.Id ' + ent.Id);
            System.assertEquals(caseObj.EntitlementId, ent.Id);
        }
    }

    @IsTest
    static void myUnitTest_two() {
        Account acc = new Account(Name='testacc');
        insert acc;

        Account dudAccount = new Account(Name='DUD ACCOUNT');
        insert acc2;

        Contact con = new Contact(FirstName='john', LastName='doe', Email='john@doe.com', AccountId=acc.Id);
        insert con;

        Asset ass = new Asset(AccountId=acc.Id,ContactId=con.Id, Name='testing');
        insert ass;

        Entitlement ent = new Entitlement(Name='Testing', AccountId=dudAccount.Id,  StartDate=Date.valueOf(System.now().addDays(-2)), EndDate=Date.valueOf(System.now().addYears(2)), AssetId=ass.Id);
        insert ent;

        EntitlementContact ec = new EntitlementContact(EntitlementId=ent.Id, ContactId=con.Id);
        insert ec;

        List<Case> listC = new List<Case>();
        List<Id> newCaseIds = new List<Id>();
        for(Integer i=0;i<20;i++){
            Case c = new Case(ContactId=con.Id, AccountId=con.AccountId, Subject='Test Subject'+i, Origin='Webform_B2B');
            listC.add(c);
        }

        Test.startTest();
        insert listC;
        Test.stopTest();

        for (Case caseObj:listC) {
            newCaseIds.add(caseObj.Id);
        }

        List<Case> entls = [SELECT EntitlementId, AssetId, ContactId, AccountId FROM Case WHERE Id IN :newCaseIds];

        for (Case caseObj:entls) {
            System.debug(caseObj.Id + ' here are the values ' + caseObj.EntitlementId + ' and here ent.Id ' + ent.Id);
            System.assertEquals(caseObj.EntitlementId, ent.Id);
        }
    }

if you are feeling brave you could try redoing the above two methods with teh @testsetup tag, 

HTH

regards
Andrew
 
Ewa FrystEwa Fryst
Hi Andrew,
Thanks for making the effort. I corrected the typo and run the test agaiin but it didn't increase the coverage at all.
I then tried the above code but i had an errror. Would you be able to fix it? I'm not a developer so any advise won't really help :-).
Many thanks
Ewa
User-added image

 
Andrew GAndrew G
Your test method will need to be inside a test class

so encapsulate the lot within a test method
 
@isTest
private class DefaultEntitlementTest {

    @IsTest 
    static void myUnitTest_one() { 
        //include code in previous answer
    }

    @IsTest 
    static void myUnitTest_two() { 
        //include code in previous answer
    } 

}

regards
andrew
Ewa FrystEwa Fryst
Ok. Thanks a lot Andrew. I will give it a go.
Ewa