+ Start a Discussion
Selim BEAUJOURSelim BEAUJOUR 

AddPrimaryContact

Hi all, 

I have a problem with this challenge :

Create a Queueable Apex class that inserts the same Contact for each Account for a specific state. Write unit tests that achieve 100% code coverage for the class.
Create an Apex class called 'AddPrimaryContact' that implements the Queueable interface.
Create a constructor for the class that accepts as its first argument a Contact sObject and a second argument as a string for the State abbreviation.
The execute method must query for a maximum of 200 Accounts with the BillingState specified by the State abbreviation passed into the constructor and insert the Contact sObject record associated to each Account. Look at the sObject clone() method.
Create an Apex test class called 'AddPrimaryContactTest'.
In the test class, insert 50 Account records for BillingState "NY" and 50 Account records for BillingState "CA". Create an instance of the AddPrimaryContact class, enqueue the job and assert that a Contact record was inserted for each of the 50 Accounts with the BillingState of "CA".
The unit tests must cover all lines of code included in the AddPrimaryContact 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.


I haven't 100% for my test class. 
 
@isTest
 public class AddPrimaryContactTest {
   
   
     @isTest static void TestList(){
         List<Account> Teste = new List <Account>();
         for(Integer i=0;i<50;i++){
             
             Teste.add(new Account(BillingState = 'CA', name = 'Test'+i));
         }
             for(Integer j=0;j<50;j++){
             
             Teste.add(new Account(BillingState = 'NY', name = 'Test'+j));
         
         }
         insert Teste;
         Contact co = new Contact();
          String state = 'CA';
     AddPrimaryContact apc = new AddPrimaryContact(co, state);
	Test.startTest();
	System.enqueueJob(apc);
     Test.stopTest();
         for (Account t:Teste){
             if( t.BillingState == 'CA'){
               	  
             	System.assertEquals(1, t.Number_of_contacts__c);
            
             
         }
         }      
}
 }
 
public class AddPrimaryContact implements Queueable{
    private Contact c;
    private String state;
    public  AddPrimaryContact(Contact c, String state){
        this.c = c;
        this.state = state;
        
    }
     public void execute(QueueableContext context) {
        List<Account> ListAccount = [SELECT ID, Name FROM ACCOUNT WHERE BillingState = :state LIMIT 200];
         for (Account l:ListAccount){
             for (Contact co:l.Contacts){
                 
                 c = co.clone(false,false,false,false);
                 insert c;
             }
                 
                 
             }
             
         }

}


Anyone can help me please?
Thanks!
Best Answer chosen by Selim BEAUJOUR
Amit Chaudhary 8Amit Chaudhary 8
Please update your Apex class like below
public class AddPrimaryContact implements Queueable
{
    private Contact c;
    private String state;
    public  AddPrimaryContact(Contact c, String state)
    {
        this.c = c;
        this.state = state;
    }
    public void execute(QueueableContext context) 
    {
         List<Account> ListAccount = [SELECT ID, Name ,(Select id,FirstName,LastName from contacts ) FROM ACCOUNT WHERE BillingState = :state LIMIT 200];
         List<Contact> lstContact = new List<Contact>();
         for (Account acc:ListAccount)
         {
                 Contact cont = c.clone(false,false,false,false);
                 cont.AccountId =  acc.id;
                 lstContact.add( cont );
         }
         
         if(lstContact.size() >0 )
         {
             insert lstContact;
         }
             
    }

}
Test class like below
@isTest
public class AddPrimaryContactTest 
{
     @isTest static void TestList()
     {
         List<Account> Teste = new List <Account>();
         for(Integer i=0;i<50;i++)
         {
             Teste.add(new Account(BillingState = 'CA', name = 'Test'+i));
         }
         for(Integer j=0;j<50;j++)
         {
             Teste.add(new Account(BillingState = 'NY', name = 'Test'+j));
         }
         insert Teste;

         Contact co = new Contact();
         co.FirstName='demo';
         co.LastName ='demo';
         insert co;
         String state = 'CA';
      
          AddPrimaryContact apc = new AddPrimaryContact(co, state);
          Test.startTest();
            System.enqueueJob(apc);
          Test.stopTest();
      }
 }
I tested same code in my developer org and completed challange.

Let us know if this will help you.

Thanks
Amit Chaudhary
 

All Answers

Amit Chaudhary 8Amit Chaudhary 8
Please update your Apex class like below
public class AddPrimaryContact implements Queueable
{
    private Contact c;
    private String state;
    public  AddPrimaryContact(Contact c, String state)
    {
        this.c = c;
        this.state = state;
    }
    public void execute(QueueableContext context) 
    {
         List<Account> ListAccount = [SELECT ID, Name ,(Select id,FirstName,LastName from contacts ) FROM ACCOUNT WHERE BillingState = :state LIMIT 200];
         List<Contact> lstContact = new List<Contact>();
         for (Account acc:ListAccount)
         {
                 Contact cont = c.clone(false,false,false,false);
                 cont.AccountId =  acc.id;
                 lstContact.add( cont );
         }
         
         if(lstContact.size() >0 )
         {
             insert lstContact;
         }
             
    }

}
Test class like below
@isTest
public class AddPrimaryContactTest 
{
     @isTest static void TestList()
     {
         List<Account> Teste = new List <Account>();
         for(Integer i=0;i<50;i++)
         {
             Teste.add(new Account(BillingState = 'CA', name = 'Test'+i));
         }
         for(Integer j=0;j<50;j++)
         {
             Teste.add(new Account(BillingState = 'NY', name = 'Test'+j));
         }
         insert Teste;

         Contact co = new Contact();
         co.FirstName='demo';
         co.LastName ='demo';
         insert co;
         String state = 'CA';
      
          AddPrimaryContact apc = new AddPrimaryContact(co, state);
          Test.startTest();
            System.enqueueJob(apc);
          Test.stopTest();
      }
 }
I tested same code in my developer org and completed challange.

Let us know if this will help you.

Thanks
Amit Chaudhary
 
This was selected as the best answer
Selim BEAUJOURSelim BEAUJOUR
Thank you Amit!
Artsiom RalevichArtsiom Ralevich
Amit is good, but I want to present alternative code.
public class AddPrimaryContact implements Queueable{
    private Contact cont;
    private String strState;
    
    //Constructor
    public AddPrimaryContact (Contact c, String strState){
        this.cont = c;
        this.strState = strState;
    }
    
    public void execute(QueueableContext context) {
        List<Account> accounts = [SELECT Id FROM Account WHERE BillingState = :strState LIMIT 200];
        List<Contact> arrContNew = New List<Contact>() ;
        
        for (Account account : accounts) {
          Contact contNew = cont.clone(false, true);
          contNew.AccountId = account.Id;
          arrContNew.add(contNew);
        }
		if ( arrContNew.size() > 0 ){ insert arrContNew; }
    }
}
 
@isTest
public class AddPrimaryContactTest {

    @isTest static void testQueueable(){
        //<-----@testSetup
        List<Account> accounts = new List<Account>();
        for (Integer i = 0; i < 50; i++){accounts.add(new Account(name = 'acc' + i, BillingState = 'NY')); }
        for (Integer i = 50; i < 100; i++){accounts.add(new Account(name = 'acc' + i, BillingState = 'CA')); }
        insert accounts;
        
      	String strState = 'CA';
        Contact cont = new Contact(LastName = 'TstsName');
        AddPrimaryContact updater = new AddPrimaryContact(cont, strState);
        //<-----@testSetup

        //<-----@testExecution
        Test.startTest();
        	System.enqueueJob(updater);
        Test.stopTest();
        //<-----@testExecution
        
        //<-----@testResult
        System.assertEquals(50, [select count() from Contact where accountID IN (SELECT id FROM Account WHERE BillingState = :strState)]);   
        //<-----@testResult
    }
}

Differences: 
1. cont.clone(false, true);
2. Not neccesary to insert sample Contact.
3. assert statement was addedd.

Thanks!
 
dennis.nl1970dennis.nl1970
I had trouble completing this challenge too. I fixed it by using Amits answer, but just out of curiousity: what am I doing wrong here?

This was my AddPrimaryContact class
public class AddPrimaryContact implements Queueable {
    
    private Contact mainContact;
    private list<Account> accounts;
    
    public AddPrimaryContact (Contact c, String abbr) {
        this.mainContact = c;
        this.accounts = [Select Id, Name From Account Where BillingState = :abbr limit 200];
    }
    
    public void execute (QueueableContext context) {

        list<Contact> newContacts = new list<Contact>();                
        for (Account a :this.accounts) {
            Contact newContact = this.mainContact.Clone();
            newContact.AccountId = a.Id;
            newContacts.Add(newContact);
        }
        insert newContacts;
    }
}
And this was my Test Class
@isTest
public class AddPrimaryContactTest {
    
    @testSetup
    public static void setup() {
        list<Account> newAccounts = new list<Account>();        
        for (Integer x = 1; x <= 100; x++) {
            String billingState = Math.Mod(x, 2) == 0 ? 'NY' : 'CA';
            newAccounts.Add(new Account(Name = 'SomeAccountName-' + x, BillingState = billingState));
        }
        insert newAccounts;           
    }
    
	@isTest    
    public static void testAddPrimaryContact() {

        Contact newContact = new Contact (FirstName = 'MyFirstName', LastName = 'MyLastName', Email = 'myname@mydomain.com');
        AddPrimaryContact addPrimaryContactCtrl = new AddPrimaryContact (newContact, 'CA');

        Test.startTest();
        system.enqueueJob(addPrimaryContactCtrl);
        Test.stopTest();
        
        for (Account a :[Select Id, BillingState, (Select Id From Contacts) From Account]) {
            system.assert((a.BillingState == 'NY' && a.Contacts.Size() == 0) || (a.BillingState == 'CA' && a.Contacts.Size() == 1));
        }
	}
}
The test succeeded and coverage was 100%. Despite, it kept telling me "The 'AddPrimaryContactTest' test class doesn't appear to be using the 'AddPrimaryContact' class" and I wasn't able to find out what I did wrong. I know the SOQL was supposed to be in the execute method, but I tried that. I also tried it with inserting the newContact and using a variable for 'CA'. Everytime the same message. Any ideas?

Dennis.

 
Artsiom RalevichArtsiom Ralevich
Hi Dennis,
I tryed to use @testSetup in my code, but get the same message. To pass the test I placed @public static void setup() to public static void testAddPrimaryContact().
I don't know why @testSetup doesn't works ...
@isTest
public class AddPrimaryContactTest {
    
	@isTest    
    public static void testAddPrimaryContact() {
		
		list<Account> newAccounts = new list<Account>();        
        for (Integer x = 1; x <= 100; x++) {
            String billingState = Math.Mod(x, 2) == 0 ? 'NY' : 'CA';
            newAccounts.Add(new Account(Name = 'SomeAccountName-' + x, BillingState = billingState));
        }
        insert newAccounts;
	
        Contact newContact = new Contact (FirstName = 'MyFirstName', LastName = 'MyLastName', Email = 'myname@mydomain.com');
        AddPrimaryContact addPrimaryContactCtrl = new AddPrimaryContact (newContact, 'CA');

        Test.startTest();
        system.enqueueJob(addPrimaryContactCtrl);
        Test.stopTest();
        
        for (Account a :[Select Id, BillingState, (Select Id From Contacts) From Account]) {
            system.assert((a.BillingState == 'NY' && a.Contacts.Size() == 0) || (a.BillingState == 'CA' && a.Contacts.Size() == 1));
        }
	}
}

 
Ashish Tondare SFDCAshish Tondare SFDC
Hey Guys,

I tried all the permutations and combinations of the solutions mentioned above but i was unable to complete the challenge. My Code Coverage is 100%. Any help is appreciated. Below is my code.

Class
-------------------------
public class AddPrimaryContact implements Queueable {
    
    private contact c;
    private string abbr;
    List<Account> accs;
    public AddPrimaryContact(Contact con, String state){
        this.c = con;
        this.abbr = state;
    }
    
    public void execute(QueueableContext context) {
    
        accs = [Select Id, Name From Account Where BillingState = :abbr limit 200];
        system.debug('Size'+accs.size());
        List<Contact> cons = new List<Contact>();
        for(Account a:accs){
            Contact con = this.c.clone(false, false,false,false);
            con.AccountId = a.Id;
            cons.add(con);
        }
        insert cons;
    }
}

Test Class
----------------------
@isTest
private class AddPrimaryContactTest {

    @isTest

    static void setUp(){
        List<Account> accs = new List<Account>();
        for(Integer i = 0; i<50; i++){
            accs.add(new Account(Name='Test'+i,BillingState = 'NY'));
        }
        for(Integer i = 50; i<100; i++){
            accs.add(new Account(Name='Test'+i,BillingState = 'CA'));
        }
        insert accs;
    }
    
    static testMethod void testQue(){
        Contact newContact = new Contact (FirstName = 'MyFirstName', LastName = 'MyLastName', Email = 'myname@mydomain.com');
        setUp();
        AddPrimaryContact  apc = new AddPrimaryContact (newContact,'CA');
        Test.startTest();
        system.enqueueJob(apc);
        Test.stopTest();
        
    }
}

Regards,
Ashish
Rajesh DhawanRajesh Dhawan
Hey dennis.nl1970 & others,

First of all, I was feeling really guilty searching for the solution to this challenge. Only after wasting half a day tring to figure out what I did wrong even after getting 100% coverage and then looking at Amit Chaudhary 8's test code and spending another 2 hours comparing mine, which were 99.99% similar, I found out the issue (which is frustrating & nonsense) that most of us here is facing.

Its that space while constructing the AddPrimaryContact object. i.e new AddPrimaryContact (newContact, 'CA'); shouldnt have a space. You hear that right!!!
If you just remove the space between the classname and "("  the Challenge passes. It should be new AddPrimaryContact(newContact, 'CA');

Even though this was frustrating, at the end I was satisfied that my solution was correct and it was only due to system error that my challenge wasnt completing. :) :D
anuragsinghnsanuragsinghns
@Rajesh Thanks for that really stupid :)
anuragsinghnsanuragsinghns
I spent 2 hours trying to debug that issue wondering what I did wrong
Fnu SumitFnu Sumit
even i used all code mention above but test method is not covering 100%code.
i used run all test before to check challange but still same error.
i dont know why these code are not cover the 100% 
please anyone can help.
public class AddPrimaryContact implements Queueable
{
    private Contact c;
    private String state;
    public  AddPrimaryContact(Contact c, String state)
    {
        this.c =c;
        this.state = state;
    }
    public void execute(QueueableContext context) 
    {
         List<Account> ListAccount = [SELECT ID, Name ,(Select id,FirstName,LastName from contacts ) FROM ACCOUNT WHERE BillingState = :state LIMIT 200];
         List<Contact> lstContact = new List<Contact>();
         for (Account acc:ListAccount)
         {
                 Contact cont = c.clone(false,false,false,false);
                 cont.AccountId =  acc.id;
                 lstContact.add(cont);
         }
         
         if(lstContact.size() >0 )
         {
             insert lstContact;
         }
             
    }

}
 
@isTest
public class AddPrimaryContactTest 
{
     @isTest static void TestList()
     {
         List<Account> Teste = new List <Account>();
         for(Integer i=0;i<50;i++)
         {
             Teste.add(new Account(BillingState = 'CA', name = 'Test'+i));
         }
         for(Integer j=0;j<50;j++)
         {
             Teste.add(new Account(BillingState = 'NY', name = 'Test'+j));
         }
         insert Teste;

         Contact co = new Contact();
         co.FirstName='demo';
         co.LastName ='demo';
         insert co;
         String state = 'CA';
      
          AddPrimaryContact apc = new AddPrimaryContact(co, state);
          Test.startTest();
            System.enqueueJob(apc);
          Test.stopTest();
      }
 }

 
Rajeshwar PatelRajeshwar Patel
Hi All,
I did everthing mentioned above but code zcoverage in not 100%. Here is my code . Can any one please tell whats wrong on it 

@isTest
public class AddPrimaryContactTest {
    
    public static testMethod void testPrimaryContactTest(){  
        List<Account> a = new List<Account>();
         For(integer i=0;i<50;i++){
             a.add(new Account(BillingState = 'CA', name = 'Test'+i));
         }
         For(integer j=0;j<50;j++){
             a.add(new Account(BillingState = 'NY', name = 'Test'+j));              
         }
       insert a;           
       }   
    
    public static testMethod Void testAddPrimaryContact(){
        Contact ccc =new Contact(FirstName='Kaproor',LastName='Rani');
        insert ccc;
       String State='CA';
    
     // Create our Queueable instance
             AddPrimaryContact apc = new AddPrimaryContact(ccc, State);   
        // startTest/stopTest block to force async processes to run
        Test.startTest();      
           System.enqueueJob(apc);
        Test.stopTest();
    //System.assertEquals(50, [select count() from contact where accountId IN(select id from account where Billingstate=:state)]);
}
}
Rajeshwar PatelRajeshwar Patel
I modified My Assert statement  but still Code Coverage in not 100%

for(Account a: [select id ,BillingState ,(select id  from contacts) from Account]){
            System.assert((a.BillingState=='NY'&& a.contacts.size()==0) || (a.BillingState=='CA'&& a.contacts.size()==1));
Sampat_KhuranaSampat_Khurana
Use the below instead:

System.assertEquals(50, [select count() from Contact where accountID IN (SELECT id FROM Account WHERE BillingState = 'CA')]);
Sumanth MeenavolSumanth Meenavol
I have different errror , and I have 100% test coverage , does any one got the this error ?

Challenge Not yet complete... here's what's wrong: 
The 'AddPrimaryContactTest' test class doesn't appear to be using the 'AddPrimaryContact' class.
Arun AdepuArun Adepu
Hi guys, 
Here my test code with 100%. If you try this you can pass challange.

@isTest
public class AddPrimaryContactTest {
@isTest
    static void testme(){
        list<account> acclist=new list<account>();
        for(integer i=0;i<50; i++){
            acclist.add(new account(name='test'+i, BillingState='NY'));
        }
        for(integer j=0; j<50; j++){
            acclist.add(new account(name='test'+j, billingState='CA'));
        }
        insert acclist;                            
        
        test.startTest();
        contact co=new contact();
        co.firstname='tst1';
        co.LastName='tst2';
        string state='c';
        insert co;
        addprimarycontact apc=new addprimarycontact(co, 'CA');  
        system.enqueueJob(apc);
        test.stopTest();
        
    }
    
}

class :

public class AddPrimaryContact Implements Queueable {
    
    private contact contacts;
    private string state;
    
    public AddPrimaryContact(contact contacts, string state){
        this.contacts=contacts;
        this.state=state;
    }
    public void execute(QueueableContext context){
        List<Account> acclist=[select id, name,(select id, lastname, firstname, accountId from contacts) from account where Billingstate=:state limit 200];
    list<contact>con=new list<contact>();
        for(account acc:acclist){
            contact c=contacts.clone();
            c.AccountId=acc.id;
            con.add(c);
        }
        insert con;
        
    }
}
 
Prashant MaxsteelPrashant Maxsteel
Hi Everyone,

I have a query /issue with the requirement here.
Functionally, what we are doing is, creating clones i.e. new Child Contacts for each of the max 200 identified Parent Contact.
Isn't the relationship between Account and Contact M:M in a CRM world? If so, how do we instead of insert rather associate the passed Contact record to each of the Account record?
Vincent RizzoVincent Rizzo
Hello everyone after some time suffering the  "Constructor not defined error" I went back over my code and noticed that I had put void in front of the second AddPrimaryContact, removing it removed the problem. Does anyone have the technical reason why this is?
Janet EpebinuJanet Epebinu
Hello Vincent, the 'second' AddPrimaryContact is a contructor. A constructor is special method that has no return value and takes the name of the class.
SHISHIR BANSALSHISHIR BANSAL
HI Guys, 

Here is the solution i propose, have a look and comment below 


public class AddPrimaryContact implements Queueable {



    private Contact globalSObject;
    private String globalState;
    private List<Contact> conList = new List<Contact>() ; 




   public AddPrimaryContact(Contact sObjs , String st){
           this.globalSObject = sObjs;
           this.globalState   = st;

   }


    public void execute(QueueableContext context) {


        List<Account>  accList = [Select Id, BillingState, (Select Id , LastName , Email,AccountId from Contacts) from Account where BillingState =:globalState Limit 200];


        for(Account acc : accList){



            Contact cObj = globalSObject.clone(false,true);
            cobj.AccountId = acc.Id;
            conList.add(cobj);

        }
        //Do some action here

        if(conList.size() >0){
        Database.insert(conList , false);
    }
    }
}
SHISHIR BANSALSHISHIR BANSAL
And Test Class 

@isTest
private class AddPrimaryContactTest {
    
    @testSetup 
    static void setup() {
        // Implement test code

        List<Account> accList = new List<Account>();

        for(Integer i = 0 ; i < 50 ; i++){
            accList.add(new Account(BillingState = 'NY' , Name = 'Test'+i));
        }


        for(Integer i =50 ; i <100; i++ ){

            accList.add(new Account(BillingState = 'CA', Name = 'test'+i));
        }


        if(accList.size() == 100){
            Database.insert(accList,false);
        }



        

    }

    
    
    @isTest static void test_method_one() {
        // Implement test code
     

        Contact cObj = new Contact (LastName = 'Bansal', Email = 'xyz@gmail.com');
        Database.insert(cObj,false);
        String st = 'CA';

      AddPrimaryContact classObj = new AddPrimaryContact(cObj ,st);

      Test.startTest();
         System.enqueueJob(classObj);
      Test.stopTest();

      System.assertEquals(50 , [select count() from Contact where accountID IN (SELECT id FROM Account WHERE BillingState = :st)]);

     

    }
    
}
shaji syed syedshaji syed syed
Reoved the white space in here as suggested and it worked!
Changed from AddPrimaryContact apc = new AddPrimaryContact (c, 'CA'); to AddPrimaryContact apc = new AddPrimaryContact(c, 'CA');
Thank you!!!