+ Start a Discussion
huskerwendyhuskerwendy 

How to raise code coverage on test for Trigger

I have a trigger that is only covered at 48% and I'm trying to get it closer to 100%. What can I do to up the code coverage?

Here's the trigger. The Bolded lines are not covered:

trigger trgAssetAfterInsertUpdateDelete on Asset (after insert, after update, after delete) {
    if (trigger.isInsert || trigger.isUpdate){
        /*Trigger will update the Client_Since__c field on the account with the first purchase date for all assets.
          If the Asset has VersaDoc and the account doesn't have a VersaDoc Project Account Team Member,
          it will assign the next VersaDoc Project manager from the assignment groups to the Account Team.*/
        // create a set of all the unique accountIds
        Set<id> accountIds= new Set<id>();
        Set<id> accountTeamAccountIds = new Set<id>(); // set of accountIDs that have VersaDoc in the asset
        for (Asset a : Trigger.new){
            accountIds.add(a.AccountId);
            if (a.HasVersadoc__c == 1 || a.HasVersadocStudio__c == 1 ) {
                accountTeamAccountIds.add(a.AccountId);
            }  
        }
          
        // create map of accountids and minimum purchase date
        map<ID, Date> acctSinceDate = new map<ID, Date>(); 
        AggregateResult[] groupedResults = [Select AccountId, MIN(PurchaseDate) MinPurchaseDate From Asset where AccountID in :accountIds GROUP BY AccountId];
        for (AggregateResult ar : groupedResults)  {
            acctSinceDate.put(String.valueof(ar.get('AccountId')), Date.valueof(ar.get('MinPurchaseDate')) );
        }      
        // create a map of accounts to update
        map<String, Account> accts = new map<String, Account>([Select Id, Client_Since__c from Account Where Id in :acctSinceDate.keySet()]);
        // update Account ClientSince field with MinimumPurchaseDate value
        //iterate over the list of accounts and assign the ClientSince date
        for (Account acct : accts.values()){
            acct.Client_Since__c = acctSinceDate.get(acct.Id);
        }
        if (accts.size()>0){
            update(accts.values());
        }
        // get the assignment group id for the VersaDoc Project Managers group         
        list<Assignment_Group_Name__c> asgnGroupNameIDs = [SELECT Id FROM Assignment_Group_Name__c WHERE Name = 'Support - VersaDoc Project Managers' limit 1];
        system.debug('asgnGroupnameIDs is ' + asgnGroupNameIDs);
   
        Assignment_Groups__c[] asgnGroups = new List<Assignment_Groups__c>([SELECT Group_Name__c, User__c, Last_Assignment__c, Millisecond__c
                                   FROM Assignment_Groups__c
                                   WHERE Group_Name__c in :asgnGroupNameIds
                                   AND Active__c = 'True' AND User_Active__c = 'True'
                                   ORDER BY Last_Assignment__c, Millisecond__c] );                                   
   
        Integer groupCount = asgnGroups.size();
   
        System.debug('>>>>>asgnGroups: '+asgnGroups);  
        if (asgnGroups.isEmpty()) return;                     

        //loop through list of accounts and get the accounts w/o VersaDoc Project Manager
        AccountTeamMember[] NewMembers = new AccountTeamMember[]{};  //list of new team members to add
        AccountShare[] newShare = new AccountShare[]{};  //list of new shares to add
        Map<id, Account> acctsToUpdate = new Map<id, Account>([Select a.Id, (Select Id, AccountId From AccountTeamMembers WHERE TeamMemberRole = 'VersaDoc Project Manager' limit 1) From Account a Where a.Id in :accountTeamAccountIds]);
        Integer cnt = 0;
        for (Account a : acctsToUpdate.values()){
            if (a.AccountTeamMembers == null || a.AccountTeamMembers.isEmpty()) {
                AccountTeamMember TeamMemberAd=new AccountTeamMember();
                TeamMemberAd.AccountId=a.id;
                TeamMemberAd.UserId=asgnGroups[cnt].User__c;
                TeamMemberAd.TeamMemberRole = 'VersaDoc Project Manager';
                NewMembers.add(TeamMemberAd);  
                datetime now = datetime.now();
                asgnGroups.get(cnt).Last_Assignment__c=now;
                asgnGroups.get(cnt).Millisecond__c = now.millisecondGMT();
                cnt ++;
                if (cnt == groupCount){ cnt = 0;}      
            }
        }


        //insert any valid members then add their share entry if they were successfully added
        Database.SaveResult[] lsr = Database.insert(NewMembers,false);
        Integer newcnt=0;
        for(Database.SaveResult sr:lsr){

            if(!sr.isSuccess()){
                Database.Error emsg = sr.getErrors()[0];
                system.debug('\n\nERROR ADDING TEAM MEMBER:'+emsg);
            }else{
                newShare.add(new AccountShare(UserOrGroupId=NewMembers[newcnt].UserId, AccountId=NewMembers[newcnt].Accountid, AccountAccessLevel='Edit',OpportunityAccessLevel='Edit'));
            }
                newcnt++;          
        }

        //insert the new shares
        Database.SaveResult[] lsr0 =Database.insert(newShare,false);
        Integer newcnt0=0;
        for(Database.SaveResult sr0:lsr0){
            if(!sr0.isSuccess()){
                Database.Error emsg0=sr0.getErrors()[0];
                system.debug('\n\nERROR ADDING SHARING:'+newShare[newcnt0]+'::'+emsg0);
            }
                newcnt0++;
        }
        // update assignment groups with their LastAssignmentDate
        update asgnGroups;                                          
    } else if (trigger.isDelete){

        // create a set of all the unique accountIds
        Set<id> accountIds = new Set<id>();
        for (Asset a : Trigger.old)
            accountIds.add(a.AccountId);   
          
        // create map of accountids and minimum purchase date
        map<ID, Date> acctSinceDate = new map<ID, Date>();
       
        AggregateResult[] groupedResults = [Select AccountId, MIN(PurchaseDate) MinPurchaseDate From Asset where AccountID in :accountIds GROUP BY AccountId];
        for (AggregateResult ar : groupedResults)  {
            acctSinceDate.put(String.valueof(ar.get('AccountId')), Date.valueof(ar.get('MinPurchaseDate')) );
        }
        // create a map of accounts to update
        map<string, Account> accts = new map <string, Account>([Select Id, Client_Since__c from Account Where Id in :accountIds]);
        for (Account acct : accts.values()){
            // if there's a value in the acctSinceDate map, update the Client_Since__c date to that date, otherwise set to null.
            if(acctSinceDate.ContainsKey(acct.Id)){
                acct.Client_Since__c = acctSinceDate.get(acct.Id);
            }else {
                acct.Client_Since__c = null;
            }
        }
        update(accts.values());
    }
}

Here's the Test class:
@isTest
private class TestTrgAssetAfterInsertUpdateDelete {
    static testMethod void myUnitTest() {
       //create runas user
        User u = TestDataFactory.createTestRunAsUser('Sales Assistant', 'Sales Assistant');
       
        System.runAs(u) {   
            Date firstPurchaseDate = date.newinstance(2013, 12, 15);
            Date newPurchaseDate = date.newinstance(2013, 11, 15); 
            list<Account> accts = new list<Account>();
            list<User> users = new list<User>();
           
            accts = TestDataFactory.createTestAccounts(2, 'Printers', 'Client');
            users = TestDataFactory.createMulitpleUsers(2, 'Standard User', 'Product Support Rep');
            Assignment_Group_Name__c agn = TestDataFactory.createAssignmentGroup('Support - VersaDoc Project Managers', 'Accounts');     
   
            Test.StartTest();  
                list<Asset> assts = new list<Asset>();
                //create assets for account and check that the client since date was populated
                TestDataFactory.CreateAssets(accts, firstPurchaseDate, 'PrinterPresence Silver Level', 'Purchased', 160.00, 2000.00);
                checkClientSinceDate(accts, firstPurchaseDate);
                performCreateAdditionalAssets(u.Id, accts);
                checkClientSinceDate(accts, firstPurchaseDate);
                performUpdateOriginalPurchaseDate(u.Id, accts, newPurchaseDate);
                checkClientSinceDate(accts, newPurchaseDate);
                performCreateVersaDocAssets(u.Id, accts);
                performDeleteAssets(u.Id, accts);  
                checkAccountTeamMember(accts, users);                                   
            Test.StopTest();     
        }
    }

    public static void checkClientSinceDate(list<Account> accounts, Date firstPurchaseDate){
          //check results of accounts to be sure ClientSince date was updated to the PurchaseDate
         list <Account> accs = [Select Id, Client_Since__c from Account Where Id in:accounts];
         for (Account a : accs){
            System.assertEquals(firstPurchaseDate, a.Client_Since__c);  
         } 
    }
   
    public static void performCreateAdditionalAssets(String userid, list<Account> accounts){
       //  list<Account> accts = new list<Account>([Select id from Account WHERE CreatedbyId =: userid and Id in : accounts]);            
        list <Asset> insertedAsst = [Select Id from Asset where CreatedbyId =: userid and AccountId in : accounts];     
        date now = date.today();
       
        //update previous asset to Attritioned-Upgrade
        for (Asset ass : insertedAsst){
            ass.Status = 'Attritioned-Upgrade';
            ass.UsageEndDate = date.today();
        }      
        update insertedAsst;
       
        // create new assets and check client since date
        TestDataFactory.CreateAssets(accounts, now, 'PrinterPresence Gold Level', 'Purchased', 210.00, 500.00);
    }
   
    public static void performUpdateOriginalPurchaseDate(String userid, list<Account> accounts, Date newPurchaseDate){    
        // get a list of the original assets   
        list <Asset> insertedAsst = [SELECT Id FROM Asset WHERE CreatedbyId =: userid AND AccountId in: accounts AND Status = 'Attritioned-Upgrade'];
               
        //update original asset purchase date
        for (Asset ass : insertedAsst){
            ass.PurchaseDate = newPurchaseDate;
        }      
        update insertedAsst;
    }
   
    public static void performDeleteAssets(String userid, list<Account> accounts){
        // delete assets for all accounts
        list <Asset> AssetToDelete = [Select Id from Asset where CreatedbyId =: userid and AccountId in: accounts];     
        delete AssetToDelete;
       
        checkClientSinceDate(accounts, Null);
    }
   
    public static void performCreateVersaDocAssets(String userid, list<Account> accounts){
        // add PrinterPresence Platinum level Asset (Has VersaDoc) and check that the VersaDoc Project Manager AccountTeam Members have been added to the account.
  list<Asset> assets = new list<Asset>();
        Set<id> accountIds= new Set<id>();
       
    TestDataFactory.createProduct('Platinum Level', 'VersaDoc');
   
        date now = date.today();
        assets = TestDataFactory.createAssets(accounts, now, 'Platinum Level', 'Purchased-Upgrade', 310.00, 7500.00);
        system.debug('-----assets are ' + assets);

        list <Asset> assetsVd = [select Id, Name, AccountId, HasVersadoc__c, HasVersadocStudio__c, Armor_date__c, Status, Product2Id, Product2.Name, Product2.ProductCode, Product2.Family, Product2.HasVersadoc__c FROM Asset where Id in: assets];
        system.debug('-------assetsVd are ' + assetsVd);
       
        Product2 prod = [select Id, Name, Included_Components__c, HasVersadoc__c from Product2 where Name =: 'Platinum Level'];
  system.debug('------products are ' + prod);

       // if asset contains versadoc product add to account list
        for(Asset a : assetsVd){
        if (a.HasVersadoc__c == 1 || a.HasVersadocStudio__c ==1){
          accountIds.add(a.AccountId);
         }          
     }
    }
   
    public static void checkAccountTeamMember(list<Account> accounts, list<User> users){
     // add users to assignment group
        AccountTeamMember[] NewMembers = new AccountTeamMember[]{};  //list of new team members to add
        AccountShare[] newShare = new AccountShare[]{};  //list of new shares to add
        Assignment_Group_Name__c agn = TestDataFactory.createAssignmentGroup('Support - VersaDoc Project Managers', 'Accounts');     
        TestDataFactory.addUsersToAssigmentGroup(users, agn);
            
        Assignment_Groups__c[] asgnGroups = new List<Assignment_Groups__c>([SELECT Group_Name__c, User__c, Last_Assignment__c, Millisecond__c
         FROM Assignment_Groups__c
            WHERE Group_Name__c =: agn.id
            AND Active__c = 'True' AND User_Active__c = 'True'
            ORDER BY Last_Assignment__c, Millisecond__c] );   
 
  Integer groupCount = asgnGroups.size();
  Map<id, Account> acctsToUpdate = new Map<id, Account>([Select a.Id, (Select Id, AccountId From AccountTeamMembers WHERE TeamMemberRole = 'VersaDoc Project Manager' limit 1) From Account a Where a.Id in :accounts]);
  Integer cnt = 0;
   for (Account a : acctsToUpdate.values()){
    system.debug('----acctsToUpdate.values is ' + acctstoUpdate.values());
   
       if (a.AccountTeamMembers == null || a.AccountTeamMembers.isEmpty()) {
        system.debug('---- in the If Statement ' + a.id);
           AccountTeamMember TeamMemberAd=new AccountTeamMember();
              TeamMemberAd.AccountId=a.id;
              TeamMemberAd.UserId=asgnGroups[cnt].User__c;
              TeamMemberAd.TeamMemberRole = 'VersaDoc Project Manager';
              NewMembers.add(TeamMemberAd);  
              datetime now = datetime.now();
              asgnGroups.get(cnt).Last_Assignment__c=now;
              asgnGroups.get(cnt).Millisecond__c = now.millisecondGMT();
              cnt ++;
              if (cnt == groupCount){ cnt = 0;}      
          }
    }   
       
        for (Account a : acctsToUpdate.values()){
            System.assertNotEquals(a.AccountTeamMembers, Null);
        } 
    }
}
Suresh RaghuramSuresh Raghuram
Simple when you are creating a new asset record pass the a.HasVersadoc__c == 1.
One more thing you should notice from the code coverage is it just not covered  at the if conditions so you should make sure your if conditions satisfy by providing the proper inputs.

if this answers yours like this post.
huskerwendyhuskerwendy
Hi Suree,
That's my problem, I can't pass in the HasVersadoc__c value because it's a formula field on the asset based on the product and for some reason it's not evaluating in the test class. It's always 0.

This is the Asset field formula: "Has_Versadoc__c" and it's value is either 0 or 1. 

CASE(1,IF(AND(BEGINS(TEXT(Status), "Purchased"), OR(Product2.ProductCode = "FDP-16",
INCLUDES(Product2.Included_Components__c, "VersaDoc"))), 1, 0), 1,
IF(AND(BEGINS(TEXT(Status), "Attritioned"),OR(Product2.ProductCode = "FDP-16",
INCLUDES(Product2.Included_Components__c, "VersaDoc"))), 1, 0), -1,
0)

I've even changed the formula to this and it still doesnt' work (HasVersadoc__c is a formula on the product that is working):
Product2.HasVersadoc__c

Product2 field formula: "HasVersadoc__c" (works in the test class)
IF(INCLUDES(Included_Components__c, "VersaDoc"), 1, 0)

Here are the debug lines for the products and assets:
The Debug line for products is (which shows the HasVersadoc__c = 1 on the product and VersaDoc as an IncludedComponent):
16:25:16:271 USER_DEBUG [153]|DEBUG|------products are Product2:{Name=Platinum Level, Included_Components__c=VersaDoc, Id=01t11000000UCh4AAG, HasVersadoc__c=1}

The debug line for Assets is :
16:30:41:793 USER_DEBUG [88]|DEBUG|-------assetsVd are (Asset:{Name=Platinum Level, Armor_Date__c=2014-03-05 00:00:00, Status=Purchased-Upgrade, AccountId=00111000009H1jfAAC, HasVersadocStudio__c=0, Id=02i110000009WaiAAE, HasVersadoc__c=0}, Asset:{Name=Platinum Level, Armor_Date__c=2014-03-05 00:00:00, Status=Purchased-Upgrade, AccountId=00111000009H1jgAAC, HasVersadocStudio__c=0, Id=02i110000009WajAAE, HasVersadoc__c=0})
huskerwendyhuskerwendy
Here's the error I get when I try to write that field:
Save error: Field is not writeable: Asset.HasVersadoc__c

Any help would be appreciated. I'm so frustrated because I can't get the code coverage above 48%.