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
Glenn Dailey 1Glenn Dailey 1 

Salesforce trailhead Create an Apex class that uses the @future annotation to update Account records

Create an Apex class with a method using the @future annotation that accepts a List of Account IDs and updates a custom field on the Account object with the number of contacts associated to the Account. Write unit tests that achieve 100% code coverage for the class.
Create a field on the Account object called 'Number_of_Contacts__c' of type Number. This field will hold the total number of Contacts for the Account.
Create an Apex class called 'AccountProcessor' that contains a 'countContacts' method that accepts a List of Account IDs. This method must use the @future annotation.
For each Account ID passed to the method, count the number of Contact records associated to it and update the 'Number_of_Contacts__c' field with this value.
Create an Apex test class called 'AccountProcessorTest'.
The unit tests must cover all lines of code included in the AccountProcessor class, resulting in 100% code coverage.
Run your test class at least once (via 'Run All' tests the Developer Console) before attempting to verify this challenge.

Illegal assignment from Integer to String when trying to save

code that I'm trying to use line 11 is the issue

public class AccountProcessor
{
  @future
  public static void countContacts(Set<id> setId)
  {
      List<Account> lstAccount = [select id,Number_of_Contacts__c , (select id from contacts ) from account where id in :setId ];
      for( Account acc : lstAccount )
      {
          List<Contact> lstCont = acc.contacts ;
         
          acc.Number_of_Contacts__c = lstCont.size(); // line 11
      }
      update lstAccount;
  }
}

 
venkat-Dvenkat-D
Did yoiu create Number_of_Contacts__c  as Number field?
Glenn Dailey 1Glenn Dailey 1
That helped that issue but now another error i did try run all
Challenge Not yet complete... here's what's wrong:
The 'AccountProcessor' class did not achieve 100% code coverage via your test methods. Make sure that you chose 'Run All' tests in the Developer Console at least once before attempting to verify this challenge.
Glenn Dailey 1Glenn Dailey 1
I did forget to add I did "run all" about 10 times is there something wrong in this unit?
Glenn Dailey 1Glenn Dailey 1
This is the second challenge in this unit that has not worked.
Amit Chaudhary 8Amit Chaudhary 8
Please try below code.
1) https://developer.salesforce.com/forums/?id=906F0000000D8hwIAC
public class AccountProcessor 
{
  @future
  public static void countContacts(Set<id> setId) 
  {
      List<Account> lstAccount = [select id,Number_of_Contacts__c , (select id from contacts ) from account where id in :setId ];
      for( Account acc : lstAccount )
      {
          List<Contact> lstCont = acc.contacts ;
          
          acc.Number_of_Contacts__c = lstCont.size();
      }
      update lstAccount;
  }
}
Test Class
@IsTest
public class AccountProcessorTest {
    public static testmethod void TestAccountProcessorTest() 
    {
        Account a = new Account();
        a.Name = 'Test Account';
        Insert a;

        Contact cont = New Contact();
        cont.FirstName ='Bob';
        cont.LastName ='Masters';
        cont.AccountId = a.Id;
        Insert cont;
        
        set<Id> setAccId = new Set<ID>();
        setAccId.add(a.id);
 
        Test.startTest();
            AccountProcessor.countContacts(setAccId);
        Test.stopTest();
        
        Account ACC = [select Number_of_Contacts__c from Account where id = :a.id LIMIT 1];
        System.assertEquals ( Integer.valueOf(ACC.Number_of_Contacts__c) ,1);
  }
  
}
Let us know if this will help you


 
Majid Ali 42Majid Ali 42
that's helpful
Majid Ali 42Majid Ali 42
but you are not updating Number_of_Contacts__c field based on the number of contacts dynamicall
deepashri hkdeepashri hk
Below can be used for 100% code coverage:
1. Create the factory class method to create the number of accounts required to be created.
className: OlderAccountsUtility

public static List<Account> createAccounts(Integer  numOfAccounts) {
        List<Account> accountList = new List<Account>();
        for(Integer i=0;i<numOfAccounts;i++)
        {
            Account account = new Account(Name='TestAccount'+i);
            accountList.add(account);
        }
        insert accountList;
        return accountList;    
    }
2. Create the factory class method to create the related contacts for the account created above.
className: RandomContactFactory

public static List<Contact> createRelatedContact(Integer numContacts, String AccountId) {
        List<Contact> contacts = new List<Contact>();
        for(Integer i=0;i<numContacts;i++) {
            Contact contact = new Contact(FirstName='TestContact' + i, LastName='TestLastName',AccountId=AccountId);
            contacts.add(contact);
            System.debug('contact '+contact);
        }
        insert contacts;
        return contacts;
}

3. Use these factory methods to create the test data for testing and pass the same to have 100% code coverage.

@isTest
public class AccountProcessorTest {
    
    @isTest
    public static void countContactsTest()
    {
        List<Id> accountIds = new List<Id>();
        Account[] account = OlderAccountsUtility.createAccounts(1);
        for(Account a : account)
        {
            accountIds.add(a.Id);
            Contact[] relatedContact = RandomContactFactory.createRelatedContact(1,a.Id);
        }
        Test.startTest();
        AccountProcessor.countContacts(accountIds);
        Test.stopTest();
       
    }
}
Ali Siddiqui 11Ali Siddiqui 11

You can also use aggregate queries for this

class AccountProcessor

public class AccountProcessor {
    
    @future
    public static void countContacts(Set<id> listId){
        List<AggregateResult> AggregateResultList =[select AccountId,count(id) from Contact where accountid 
                                                    in :listId
                                                    GROUP BY AccountId];
        list<account> accToUpdate = new List<Account>();
         
        if(!AggregateResultList.isEmpty())
        {
            for(AggregateResult agr: AggregateResultList){
                Account acc = new Account();
                acc.id = (id)agr.get('AccountId');
                acc.Number_Of_Contacts__c = (integer)agr.get('expr0');
                accToUpdate.add(acc);
            }
        }
        
        update accToUpdate;
    } 
}

Test Class

@IsTest
private class AccountProcessorTest {
    
    
    @IsTest
    private static void testFutureCallout() {
        Account a = new Account();
        a.Name = 'Test Account';
        Insert a;

        Contact cont = New Contact();
        cont.FirstName ='Test';
        cont.LastName ='contact';
        cont.AccountId = a.Id;
        Insert cont;
        
        set<Id> setAccId = new Set<ID>();
        setAccId.add(a.id);
        
        Test.startTest();
        AccountProcessor.countContacts(setAccId);
        Test.stopTest();
        
        
    }
    
    
}