0

I have a trigger that fires when an Opportunity is Closed Won, has OpportunityLineItems and those OppLineItems relate to a specific Product. The firing of the trigger creates a Case Record based on variables set it in the Trigger.

The Trigger works as expected, however I am having a little difficulty with the Test Method for the trigger. I can't seem to get a successful System.Assert for the created Case.

I have attached both the Trigger and the Test Method below. Any info as to why the Case isn't being captured in the Test Method would be great. Apologies for the length of the test method we use a lot of look ups and validations...

Trigger is as follows:

trigger Accordance_trg_AutoCaseCreate on Opportunity  (before insert, before update) {
if(Accordance_StopRecursiveTrigger.runOnce()){

//Create a list of Opportunities
List<Opportunity> ClosedWonOpps = new List<Opportunity>();

//For Opportunities that have triggered the Code and are Closed Won and have a Line Item check list is not Empty
for (Opportunity opp : trigger.new){
if (opp.StageName == 'Closed Won' && opp.HasOpportunityLineItem == true){
closedWonOpps.add(opp);
}
}

if (!closedWonOpps.isEmpty())
{

date DueDate = date.today();

List<OpportunityLineItem> olis = [SELECT UnitPrice, AccountId__c, Quantity, Opportunity_Close_Date__c, OpportunityId, PricebookEntry.Product2Id, TotalPrice, Name, PricebookEntry.Product2.Name, Description, Country__c, Country__r.Name ,CurrencyIsoCode, Opportunity.Name , Opportunity.Account.Name
                                   FROM OpportunityLineItem WHERE OpportunityId in :ClosedWonOpps];   

List<Case> caToInsert = new list<Case>();     

    for (OpportunityLineItem oli : olis){

if(oli.PricebookEntry.Product2.Name == 'Change of Company Details')
 {

 //if OpLineItem exists on Op, create a new case
   Case IPCase = new Case();

    IPCase.Due_Date__c = DueDate.addMonths(2).toStartofMonth().addDays(-1); 
    IPCase.Update_Parent_Id__c = true;  
    IpCase.RecordTypeId = '01220000000Fr0I';
    IpCase.AccountId = oli.AccountId__c;
    IPCase.Country__c = oli.Country__c;
    IPCase.CurrencyIsoCode = oli.CurrencyIsoCode;
    IPCase.Related_Opportunity__c =  oli.OpportunityId;
    IPCase.Subject = oli.Opportunity.Account.Name + ' - ' + oli.PricebookEntry.Product2.Name + ' - ' + oli.Country__r.Name;
    IPCase.Type = 'Change of Company Details';
    IPCase.origin = 'Client';
    IPCase.Priority = 'Medium';
    IPCase.Status = 'New Service';
    IPCase.Amount__c = oli.TotalPrice;
    IPCase.Narrative__c = IPCase.Subject;
    IPCase.Auto_Created_Case__c = true; 

 //Add new case to Case List ready to insert at the end
  caToInsert.add(Ipcase);    
 }

if(oli.PricebookEntry.Product2.Name == 'Compliance Hours')
{
Case IPCase1 = new Case();

    IPCase1.Due_Date__c = DueDate.addMonths(2).toStartofMonth().addDays(-1); 
    IPCase1.Update_Parent_Id__c = true;
    IpCase1.RecordTypeId = '01220000000Fr0I';
    IpCase1.AccountId = oli.AccountId__c;
    IPCase1.Country__c = oli.Country__c;
    IPCase1.CurrencyIsoCode = oli.CurrencyIsoCode;
    IPCase1.Related_Opportunity__c =  oli.OpportunityId;
    IPCase1.Subject = oli.Opportunity.Name;
    IPCase1.Type = 'Compliance Hours';
    IPCase1.origin = 'Client';
    IPCase1.Priority = 'Medium';
    IPCase1.Status = 'New Service';
    IPCase1.Amount__c = oli.TotalPrice;
    IPCase1.Narrative__c = IPCase1.Subject; 
    IPCase1.Auto_Created_Case__c = true;

caToInsert.add(Ipcase1);    
}

if(oli.PricebookEntry.Product2.Name == 'Deregistration')
{
Case IPCase2 = new Case();

    IPCase2.Due_Date__c = DueDate.addMonths(2).toStartofMonth().addDays(-1); 
    IPCase2.Update_Parent_Id__c = true;
    IpCase2.RecordTypeId = '01220000000Fr0I';
    IpCase2.AccountId = oli.AccountId__c;
    IPCase2.Country__c = oli.Country__c;
    IPCase2.CurrencyIsoCode = oli.CurrencyIsoCode;
    IPCase2.Related_Opportunity__c =  oli.OpportunityId;
    IPCase2.Subject = oli.Opportunity.Account.Name + ' - ' + oli.PricebookEntry.Product2.Name + ' - ' + oli.Country__r.Name;
    IPCase2.Type = 'De-Registration';
    IPCase2.origin = 'Client';
    IPCase2.Priority = 'Medium';
    IPCase2.Status = 'New Service';
    IPCase2.Amount__c = oli.TotalPrice;
    IPCase2.Narrative__c = IPCase2.Subject;
    IPCase2.Auto_Created_Case__c = true;

  caToInsert.add(Ipcase2);      
 }        
  }
  insert caToInsert;
     }
}
}

And here is my current test method. I expected to get 1 x case created but my assert keeps coming back as null :(

@isTest (SeeAllData=true)
public class Accordance_trg_AutoCaseCreateTest {

public static testmethod void TestClosedOp() {  

//Create Pricebook 2
Pricebook2  standardPb = [select id, name, isActive from Pricebook2 where IsStandard = true limit 1];

//Create Product
Product2 prod = new Product2 (Name='Change of Company Details', family = 'Compliance', isActive = true);
    insert prod;

//Create PriceBook Entry
PricebookEntry pbEntry = new PricebookEntry (Product2ID=prod.id, Pricebook2ID=standardPb.id, UnitPrice=50, isActive=true);
    insert pbEntry;      

//Create Profile Id   
Profile profileId = [SELECT Id FROM Profile WHERE Name = 'Standard User' LIMIT 1];    

//Create User    
User TestUser = new user();
TestUser.FirstName = 'Test';
TestUser.LastName = 'User';
TestUser.Alias = 'tuser';
TestUser.Email = '[email protected]';
TestUser.Username = '[email protected]';
TestUser.CommunityNickname = 'testuser';
testuser.ProfileId = profileid.id;
testuser.EmailEncodingKey = 'UTF-8';
TestUser.TimeZoneSidKey = 'GMT';
TestUser.LocaleSidKey = 'en_US';
testuser.LanguageLocaleKey = 'en_US';

insert TestUser;   

//Create Country   
Country__c TestCountry = new Country__c();
 TestCountry.Name = 'TestCountry';

insert TestCountry;    


//Create General Ledger Account 
c2g__codaGeneralLedgerAccount__c TestGL = new 
c2g__codaGeneralLedgerAccount__c();
TestGL.Name = 'Accounts R and P';
TestGL.c2g__ReportingCode__c = '10000';
TestGL.c2g__Type__c = 'Balance Sheet';  

insert TestGL;


//Create Account
Account testAccount = new Account();
testAccount.Name = 'Test Account2'; 
testAccount.c2g__CODAVATStatus__c = 'Home' ;
testAccount.c2g__CODACreditManager__c = TestUser.id ;
testAccount.c2g__CODATaxCalculationMethod__c = 'Gross' ;
testAccount.c2g__CODAAccountTradingCurrency__c = 'GBP' ;
testAccount.c2g__CODABaseDate1__c = 'Invoice Date' ;
testAccount.c2g__CODADescription1__c = '60 Days' ;
testAccount.c2g__CODAAccountsPayableControl__c = TestGL.id ;
testAccount.c2g__CODAAccountsReceivableControl__c = TestGL.id ;
testAccount.c2g__CODADaysOffset1__c = 60 ;
testAccount.Industry = 'retail';
testAccount.Lead_Source__c = 'referral';
testAccount.Account_Tier__c = 'unknown';
testAccount.Marketing_Sector__c = 'opticians';
testAccount.Country_of_Establishment__c = TestCountry.id;
testAccount.Registered_Street__c = '12 Test Close';
testAccount.Registered_City__c = 'RDG';
testAccount.Registered_Country__c = 'United States';
testAccount.Registered_Postal_Code__c = 'RG1 4XL';

insert testAccount;             


// Create Opportunity
Opportunity opp = new Opportunity();
opp.Name = 'Test Ops1';
opp.AccountId = testaccount.id;
opp.Type = 'Existing Client';
opp.Sector__c = 'Events';
opp.CloseDate = Date.valueOf('2018-02-02');
opp.StageName = 'Prospecting';
opp.Related_Consultant__c = 'not applicable';
insert opp;    



//create opportunity line item.
 OpportunityLineItem oli = new OpportunityLineItem(
 OpportunityId = opp.Id,
 Quantity = 5,
 PricebookEntryId = pbEntry.Id,
 Product2Id = prod.id,
 country__c = testcountry.id,
UnitPrice = 400.00
);
insert oli;   

//Query Opportunity for Update    
Opportunity oppWithLines = [
Select Amount, CloseDate, Name, HasOpportunityLineItem, 
    (Select TotalPrice,  UnitPrice,  ListPrice, 
PricebookEntry.Product2.Name, country__c
    From OpportunityLineItems) 
From Opportunity 
Where Id = :opp.Id
]; 

//Change opp to Closed Won
Test.startTest();
oppwithlines.StageName = 'Closed Won';
update oppwithlines;

Test.stopTest();    

 List<Case> caseinsert = [SELECT id, Subject, Type, related_opportunity__c FROM Case Where related_opportunity__c = :oppwithlines.id];  

System.assertEquals(1, caseinsert.size());


}    
}

Thanks All!

1 Answer 1

0

There's no point in running this trigger before insert, because the Opportunity cannot have line items at that point.

It appears that you're using a very simplistic recursion guard that forces the trigger to run only once per transaction. This is a bad idea for many reasons, but in this contest it's bad because the trigger has to run twice to get the desired effect: once on the Opportunity insert, and once on update when line items may be present.

I'd also suggest refactoring this test class into an @testSetup method and one or more test cases, and removing the seeAllData annotation. Using seeAllData=true is extremely bad practice, but you don't need it because your test class creates its own data.

You aren't using System.runAs, so there doesn't appear to be any need to create a user or profile object. You can also get the standard pricebook Id from a static method on the Test class rather than creating one.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .