+ Start a Discussion
sudha76sudha76 

Building Test Class on Contacts with Opportunity or not.

The Trigger checks the Contacts and if it has Opportunity it makes the field HasOpportunity = true. Here is the trigger which works fine:-

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

trigger CheckContacts on Contact (before update)
{

// Map is intialized here to ContactID or Contact + all OCRs

Map<Id,Contact> cIdToContactWRelRecsMap  = new Map <Id,Contact>

([select id, (select id from OpportunityContactRoles) from Contact where id IN :trigger.new]);

// In the Trigger.new list, check the map to see if the size of the OCR related list is > 0.

for (Contact c: Trigger.new) {

    if (cIdToContactWRelRecsMap.get(c.id).opportunityContactRoles.size() > 0) c.HasOpportunity__c = true;
    
     }
     
     }

/////////////////////////////////////////////////////////////////////////////////////////////////////

 

I need help in building the test class. How will I write the QUERY in this test class, here it is:-

 

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

@isTest
public class CheckContactsOppty{
    static testMethod void testContactoppty()
    {
        // First, prepare 200 contacts for the test data for which first we will create some Accounts data.
        Account acct = new Account(name='TestingReal account');
        insert acct;

        Contact[] contactsToCreate = new Contact[]{};
        for(Integer x=0; x<200; x++)
        {
            Contact ctc = new Contact(Account Id= acct.Id, lastname='Rao', firstname='Sierra');
            contactsToCreate.add(ctc);
        }

        // Now I will create the Opportunity for these contacts.

        Opportunity opptytoCreate = new Opportunity[]{};
        for (Integer x=0; x<200; x++)
        {
            Opportunity oppty = new Opportunity(Contact Id= contactsToCreate.Id, Name='BestDeal');
            opptytoCreate.add(oppty);
        }
            
        // Now query the test data if it has opportunity or not.

        Test.startTest();
        ([select contactsToCreate.id, (select id from OpportunityContactRoles) from Contact where id IN :trigger.new]);  

 


\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

 

 

Please help

 

Ritesh AswaneyRitesh Aswaney

You dont need to create 200 Contacts and Opportunities to test, however here goes :

 

public class CheckContactsOppty{
    static testMethod void testContactoppty()
    {
        // First, prepare 200 contacts for the test data for which first we will create some Accounts data.
        Account acct = new Account(name='TestingReal account');
        insert acct;
Set<Id> conIds = new Set<Id>{};
        Contact[] contactsToCreate = new Contact[]{};
        for(Integer x=0; x<200; x++)
        {
            Contact ctc = new Contact(Account Id= acct.Id, lastname='Rao', firstname='Sierra');
            contactsToCreate.add(ctc);
        }

        //insert contacts

insert contactsToCreate;
        // Now I will create the Opportunity for these contacts.

        Opportunity opptytoCreate = new Opportunity[]{};

        OpportunityContactRole[] ocrs = new OpportunityContactRole[]{};


        for (Integer x=0; x<200; x++)
        {
            Opportunity oppty = new Opportunity(AccountId = acct.Id, Name='BestDeal');
            opptytoCreate.add(oppty);
        }
         

insert opptyToCreate;

 

//now create ocrs

integer counter = 0; 

for (Contact con : contactsToCreate){

ocrs.add(new OpportunityContactRole(ContactId = con.Id, OpportunityId = opptyToCreate.get(counter++).Id ));

conIds.add(con.Id);

}

 


        Test.startTest();

insert ocrs;

Test.StopTest();

 

   
        // Now query the test data if it has opportunity or not.

for(Contact con : [Select Id, Has_Opportunity__c from Contact where Id in :conIds){

System.assertEquals(true, con.Has_Opportunity__c);

}

sudha76sudha76

Hi there,

 

Here is my final code and I added some comments just for my understanding. Let me know if got this right or not.

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

@isTest
public class  CheckContactsOppty{
    static testMethod void testContactoppty()
    {
        // First prepare 200 contacts for the test data.
        // Create one Account
        Account acct = new Account(name='TestingReal account');  
        // next insert this account.
        insert acct;
        
        // Then make sure there are no duplicates in the IDs.
        Set<Id> conIds = new Set<Id>{};

        // Next create the contacts
        Contact[] contactsToCreate = new Contact[]{};
        
        // Now use the FOR loop- iteration using a variable
        for(Integer x=0; x<200; x++)
        {
            // Now associate the Contact with the Account using the Id.
            Contact ctc = new Contact(AccountId = acct.Id, lastname='Rao', firstname='Sierra');
            contactsToCreate.add(ctc);
        }
        
        // Now insert the above Contacts
        insert contactsToCreate;
        
        // Now, I will create the Opportunity for these contacts
        Opportunity opptytoCreate = new Opportunity[]{};
        // Also create the record for the OCR table, because the contact is recorded under OCR table for each opportunity.
        OpportunityContactRole[] ocrs = new OpportunityContactRole[]{};
        
        // Again use FOR loop to create Opportunity and link to the Account ID, use the same FOR loop - iteration using a variable.
        for (Integer x=0; x<200; x++)
        {
            Opportunity oppty = new Opportunity(AccountId = acct.Id, Name='BestDealEver');
            opptytoCreate.add(oppty);
        }
        
        // now insert the opportunity.
        insert opptyToCreate;
        
        
        // Now we will create the record for OCR. Contact is recorded under OCR table so we need this logic too.
        integer counter = 0;
        
       for(Contact con:contactsToCreate)
       {
           ocrs.add(new OpportunityContactRole(ContactId = con.Id, OpportunityId = opptyToCreate.get(counter++).Id));
           conIds.add(con.Id);
       }
       
       insert ocrs;
              
       // At last we will query the test data if it has opportunity or not.
       // Use the FOR loop - iteration over a query
       // Here is the real test starts.
       
       TeststartTest();
       for(Contact con: [Select Id, HasOpportunity__c from Contact where Id in: conIds])
       {
           // Assert results
           System.assertEquals(True, con.HasOpportunity__c);
       }
       Test.StopTest();       
}

}

 

/////////////////////////////////////////////////////

 

Here is the error I am getting:-

 

 
Error

Error: Compile Error: Illegal assignment from LIST<Opportunity> to SOBJECT:Opportunity at line 29 column 9

 

 

 

 

This is Line 29 - Opportunity opptytoCreate = new Opportunity[]{};


 

/////////////////////////////////////////////////////

 

 

What else am I missing here? Please help.

 

Ritesh AswaneyRitesh Aswaney
Typo, line 29 should read

Opportunity[] opptytoCreate = new Opportunity[]{};
sudha76sudha76

I removed the TestStart() and TestStop() method. It was giving me an error. And now I am able to save it.

But the test coverage is showing 4%. So then I looked into Debug logs, and figured it out that we have a VAL Rule on Accounts which expects the Account Name to be in a certain format.

 

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Account Name should be &quot;Account - Site City&quot; format.: [Name]

/////////////////////////////////

 

The, I tried again to edit the Class name and here is what I did:-

 

 

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

@isTest
public class  CheckContactsOppty{
    static testMethod void testContactoppty()
    {
        // First prepare 200 contacts for the test data.
        // Create one Account
        Account acct = new Account(name='TestingNow - Brea', Site_City__c='Brea');  
        // next insert this account.
        insert acct;
        
        // Then make sure there are no duplicates in the IDs.
        Set<Id> conIds = new Set<Id>{};

        // Next create the contacts
        Contact[] contactsToCreate = new Contact[]{};
        
        // Now use the FOR loop- iteration using a variable
        for(Integer x=0; x<200; x++)
        {
            // Now associate the Contact with the Account using the Id.
            Contact ctc = new Contact(AccountId = acct.Id, lastname='Rao', firstname='Sierra', Title='Engineer', Phone='9765677788', Email='sierra@testingnow.com' );
            contactsToCreate.add(ctc);
        }
        
        // Now insert the above Contacts
        insert contactsToCreate;
        
        // Now, I will create the Opportunity for these contacts
        Opportunity[] opptytoCreate = new Opportunity[]{};
        // Also create the record for the OCR table, because the contact is recorded under OCR table for each opportunity.
        OpportunityContactRole[] ocrs = new OpportunityContactRole[]{};
        
        // Again use FOR loop to create Opportunity and link to the Account ID, use the same FOR loop - iteration using a variable.
        for (Integer x=0; x<200; x++)
        {
            Opportunity oppty = new Opportunity(AccountId = acct.Id, Name='BestDealEver', StageName='Prospect', CloseDate=11/24/2012);
            opptytoCreate.add(oppty);
        }
        
        // now insert the opportunity.
        insert opptyToCreate;
        
        
        // Now we will create the record for OCR. Contact is recorded under OCR table so we need this logic too.
        integer counter = 0;
        
       for(Contact con:contactsToCreate)
       {
           ocrs.add(new OpportunityContactRole(ContactId = con.Id, OpportunityId = opptyToCreate.get(counter++).Id));
           conIds.add(con.Id);
       }
       
       insert ocrs;
              
       // At last we will query the test data if it has opportunity or not.
       // Use the FOR loop - iteration over a query
       // Here is the real test starts.
       
              for(Contact con: [Select Id, HasOpportunity__c from Contact where Id in: conIds])
       {
           // Assert results
           System.assertEquals(True, con.HasOpportunity__c);
       }
              
}

}

 

/////////////////////////////////////////

 


I added all the required fields on the contact, account and opportunity level. This is the error i am getting it has to do with the way I am defining DATE.

 

Error: Compile Error: Invalid initial expression type for field Opportunity.CloseDate, expecting: Date at line 36 column 123

 

 

Opportunity oppty = new Opportunity(AccountId = acct.Id, Name='BestDealEver', StageName='Prospect', CloseDate=11/24/2012);

 

How should I define the Date here?

 

 

 

 

sudha76sudha76

So I changed to this:-

 

Opportunity oppty = new Opportunity(AccountId = acct.Id, Name='BestDealEver', StageName='Prospect', CloseDate=Date.today());

 

I was able to SAVE but the test coverage is not good only 11%.

 

It says:-

 

System.AssertException: Assertion Failed: Expected: true, Actual: false

 

I am sure it has to do with the DATE i am doing something wrong????

Ritesh AswaneyRitesh Aswaney
CloseDate = Date.today().addDays(5); Sent from my iPhone
sudha76sudha76

I still get the same error:-

 

System.AssertException: Assertion Failed: Expected: true, Actual: false

 

??

Ritesh AswaneyRitesh Aswaney
It is probably the trigger. Because the opportunities are being created after the contacts. Whereas your trigger is on opportunities. Does it work via the UI when you create test data in the same sequence as the test class? Sent from my iPhone
sudha76sudha76

No. The Trigger is on Contacts:-

 

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

 

trigger CheckContacts on Contact (before update)
{

// Map is intialized here to ContactID or Contact + all OCRs

Map<Id,Contact> cIdToContactWRelRecsMap  = new Map <Id,Contact>

([select id, (select id from OpportunityContactRoles) from Contact where id IN :trigger.new]);

// In the Trigger.new list, check the map to see if the size of the OCR related list is > 0.

for (Contact c: Trigger.new) {

    if (cIdToContactWRelRecsMap.get(c.id).opportunityContactRoles.size() > 0) c.HasOpportunity__c = true;
    
     }
     
     }

 

///////////////////////////////////

 

This is what I have and it works so far. I tested it on Contacts and the field name is checked if there is an Opportunity on the Contact and not the Account.

 

I know I am very close to resolve this...something is really missing....Ahhhhhhhhhh!!!

Ritesh AswaneyRitesh Aswaney
If you just want to get this test class to work, add in this before the assert block And after the opportunity create Update contactsToCreate; Sent from my iPhone
sudha76sudha76

The Test Class worked after commenting out the System.Assert statement.

 

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

@isTest
public class  CheckContactsOppty{
    static testMethod void testContactoppty()
    {
        // First prepare 200 contacts for the test data.
        // Create one Account
        Account acct = new Account(name='TestingNow - Brea', Site_City__c='Brea');  
        // next insert this account.
        insert acct;
        
        // Then make sure there are no duplicates in the IDs.
        Set<Id> conIds = new Set<Id>{};

        // Next create the contacts
        Contact[] contactsToCreate = new Contact[]{};
        
        // Now use the FOR loop- iteration using a variable
        for(Integer x=0; x<200; x++)
        {
            // Now associate the Contact with the Account using the Id.
            Contact ctc = new Contact(AccountId = acct.Id, lastname='Rao', firstname='Sierra', Title='Engineer', Phone='9765677788', Email='sierra@testingnow.com' );
            contactsToCreate.add(ctc);
        }
        
        // Now insert the above Contacts
        insert contactsToCreate;
        
        // Now, I will create the Opportunity for these contacts
        Opportunity[] opptytoCreate = new Opportunity[]{};
        // Also create the record for the OCR table, because the contact is recorded under OCR table for each opportunity.
        OpportunityContactRole[] ocrs = new OpportunityContactRole[]{};
        
        // Again use FOR loop to create Opportunity and link to the Account ID, use the same FOR loop - iteration using a variable.
        for (Integer x=0; x<200; x++)
        {
            Opportunity oppty = new Opportunity(AccountId = acct.Id, Name='BestDealEver', StageName='Prospect', CloseDate=Date.today().addDays(5));
            opptytoCreate.add(oppty);
        }
        
        // now insert the opportunity.
        insert opptyToCreate;
        
        
        // Now we will create the record for OCR. Contact is recorded under OCR table so we need this logic too.
        integer counter = 0;
        
       for(Contact con:contactsToCreate)
       {
           ocrs.add(new OpportunityContactRole(ContactId = con.Id, OpportunityId = opptyToCreate.get(counter++).Id));
           conIds.add(con.Id);
       }
       
       insert ocrs;
              
       // At last we will query the test data if it has opportunity or not.
       // Use the FOR loop - iteration over a query
       // Here is the real test starts.
       
              for(Contact con: [Select Id, HasOpportunity__c from Contact where Id in: conIds])
       {
           // Assert results
           //System.assertEquals(True, con.HasOpportunity__c);
       }
              
}

}

/////////////////////////////////////////////////////////////

 

When I do Run All Tests, I get 80% test coverage.

But when I do Run this Test for this class I get only 11% test coverage.

I researched and found out that The trigger (CheckContacts) will get fired only during update on Contact. Whereas in the TEST CLASS there is no UPDATE on the CONTACT.   I need to perform the DML (update) operation to invoke the Trigger. Can you show me how?

sudha76sudha76

I think I resolved it myself, but adding this piece of code here:-

 

// Now insert the above Contacts       

insert contactsToCreate;       

update contactsToCreate;

 

Now, when I run tests I get 100% test coverage on the Trigger.

 

yeahhhhhhhhhhhhhhhhh!!!! thanks so much for being so patient with me...i really did learn a lot.

 

Now I want to build more triggers but again will need some help...lol!!!

sudha76sudha76

this is my final code for test class

\\\\\\\\\\\\\\\\\\\

@isTest
public class  CheckContactsOppty{
    static testMethod void testContactoppty()
    {
        // First prepare 200 contacts for the test data.
        // Create one Account
        Account acct = new Account(name='TestingNow - Brea', Site_City__c='Brea');  
        // next insert this account.
        insert acct;
        
        // Then make sure there are no duplicates in the IDs.
        Set<Id> conIds = new Set<Id>{};

        // Next create the contacts
        Contact[] contactsToCreate = new Contact[]{};
        
        // Now use the FOR loop- iteration using a variable
        for(Integer x=0; x<200; x++)
        {
            // Now associate the Contact with the Account using the Id.
            Contact ctc = new Contact(AccountId = acct.Id, lastname='Rao', firstname='Sierra', Title='Engineer', Phone='9765677788', Email='sierra@testingnow.com' );
            contactsToCreate.add(ctc);
        }
        
        // Now insert the above Contacts
        insert contactsToCreate;
        update contactsToCreate;

        // Now, I will create the Opportunity for these contacts
        Opportunity[] opptytoCreate = new Opportunity[]{};
        // Also create the record for the OCR table, because the contact is recorded under OCR table for each opportunity.
        OpportunityContactRole[] ocrs = new OpportunityContactRole[]{};
        
        // Again use FOR loop to create Opportunity and link to the Account ID, use the same FOR loop - iteration using a variable.
        for (Integer x=0; x<200; x++)
        {
            Opportunity oppty = new Opportunity(AccountId = acct.Id, Name='BestDealEver', StageName='Prospect', CloseDate=Date.today().addDays(5));
            opptytoCreate.add(oppty);
        }
        
        // now insert the opportunity.
        insert opptyToCreate;
        
        
        // Now we will create the record for OCR. Contact is recorded under OCR table so we need this logic too.
        integer counter = 0;
        
       for(Contact con:contactsToCreate)
       {
           ocrs.add(new OpportunityContactRole(ContactId = con.Id, OpportunityId = opptyToCreate.get(counter++).Id));
           conIds.add(con.Id);
       }
       
       insert ocrs;
              
       // At last we will query the test data if it has opportunity or not.
       // Use the FOR loop - iteration over a query
       // Here is the real test starts.
       
              for(Contact con: [Select Id, HasOpportunity__c from Contact where Id in: conIds])
       {
                             
           
           // Assert results
           //System.assertEquals(True, con.HasOpportunity__c);
       }
              
}

}

//////////////////////