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
ColaCola 

Adding a Product to Opportunity in Test Class

Hi, 
I have developed and tested the following trigger in sandbox and am trying to deploy it live. 

trigger updateAccountIfOppCustomer on Opportunity (after insert, after update) {
    
    boolean isCustomer = false; 
	List<Account> acctToUpdate = new List<Account>();
    List<Opportunity> opps = new List<Opportunity>(); 
    
	Set<Id> associatedAccId = new Set<Id>() ;
    for (Opportunity opp : Trigger.new) {
        if (!(associatedAccId.contains(opp.AccountId))) { 
            associatedAccId.add(opp.AccountId) ;
        }
    }
	
	opps = [SELECT Id, AccountId, Probability, Account.Type FROM Opportunity WHERE AccountId IN : associatedAccId];
    
	for (Opportunity opp : opps) {
            if (opp.Probability == 100) {   
				opp.Account.Type  = 'Customer';
                isCustomer = true; 
			}
           else if (!(isCustomer)) {
                opp.Account.Type = 'Prospect';
			}
        if (acctToUpdate.isEmpty()) {
        	acctToUpdate.add(opp.Account);
        }
    }
    update acctToUpdate;
}

However, I am unable to get the test class working. This is what I have so far but there is an error when I try inserting the opportunity.

Error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Please make sure an opportunity product is added before switching the opportunity to a closed

@isTest
public class TestUpdateAccountIfOpp {
    static testMethod void testUpdateAccount() {
        Account a = new Account(Name='testAccount', 
                                Email_Domain__c='test', 
                                Company_Short__c='tst', 
                                Product__c='Semantria', 
                                Industry='Other', 
                                Type='Prospect');
        insert a; 
        
        Product2 prod = new Product2(Name = 'Laptop X200', 
                                     Family = 'Hardware');
        insert prod;
        
        Id pricebookId = Test.getStandardPricebookId();
        
        PricebookEntry standardPrice = new PricebookEntry(
            Pricebook2Id = pricebookId, Product2Id = prod.Id,
            UnitPrice = 10000, IsActive = true);
        insert standardPrice;
        
        
        Pricebook2 customPB = new Pricebook2(Name='Custom Pricebook', isActive=true);
        insert customPB;
        
        PricebookEntry customPrice = new PricebookEntry(
            Pricebook2Id = customPB.Id, Product2Id = prod.Id,
            UnitPrice = 12000, IsActive = true);
        insert customPrice;
        
        
        Opportunity opp = new Opportunity(Name='Test', 
                                          Account = a, 
                                          Product__c='Semantria',
                                          NextStep='test',
                                          Marketing_Channel__c='Email',
                                          PriceBook2 = customPB,
                                          Product2 = prod,
                                          City__c='test', 
                                          State_Province__c='test', 
                                          CloseDate = System.today(),
                                          Country__c='test', 
                                          AccountId=a.Id, 
                                          StageName='Closed Won - One Time', 
                                          Probability=100);
       
       insert opp; 
        
       System.assertEquals('Customer', a.Type);
    }
}
Any suggestions on how to fix this are much appreciated! 

Best Answer chosen by Cola
James LoghryJames Loghry
Sounds like you have a custom validation rule that is throwing an exception, and what the error message tells me is that in your unit test you will need to:
  1. Insert an Opportunity with a StageName other than Closed.. for instance prospecting.
  2. Insert an OpportunityLineItem that attaches the mock Product (line 14 in your example) to your Opportunity.
  3. Update the Opportunity with a StageName of Closed.