+ Start a Discussion
Gaurav AgnihotriGaurav Agnihotri 

Test class for Trigger failing

I created a trigger on Quote
trigger updateOpptyAccount on Quote (before insert,before update) {
    for (Quote QuoteInLoop : Trigger.new){
       // if(QuoteInLoop.Opportunity.name != '.'){
        Boolean sMainAccount=QuoteInLoop.Main_Account__c;
        String sMainAccountId=QuoteInLoop.AccountId;
        String sQuoteAccountId=QuoteInLoop.Pelco_Account_Name__c;
        String sQuotePriceBook=QuoteInLoop.PriceBook2Id;
        String sQuoteId=QuoteInLoop.Id;
        String sOptyId=QuoteInLoop.OpportunityId;
        //checking if price book is attached to the quote
        //if no price book exist than defaulting the standard price book
        if(sQuotePriceBook == null)
        {
            QuoteInLoop.Pricebook2Id =[SELECT Id FROM Pricebook2 WHERE Name = 'Standard Price Book' LIMIT 1].Id;
        }
       
        //if pelco quote account is null
        if (sQuoteAccountId == null)
        {
            QuoteInLoop.Pelco_Account_Name__c=sMainAccountId;
            sQuoteAccountId=sMainAccountId;
        }
        //if pelco quote account is not null
        if (sQuoteAccountId != null)
        {    
            if(sMainAccountId <>sQuoteAccountId)
              {
               //make sure pelco account is not added to opportunity
               Integer iPelAccnt1=[SELECT count() FROM Pelco_Account__c WHERE AccountName__c = :sQuoteAccountId AND OpportunityName__c =:sOptyId ];
               if(iPelAccnt1 == 0)
                 {
                      // Inserting a new Pelco Account
                      String sAccountName=[SELECT Name FROM Account WHERE Id = :sQuoteAccountId].Name;
                      List <Pelco_Account__c > PelcoAccountLst =new List <Pelco_Account__c>();
                      Pelco_Account__c PelAcc1= new Pelco_Account__c();
                      PelAcc1.OpportunityName__c=sOptyId;
                      PelAcc1.AccountName__c=sQuoteAccountId;
                      PelAcc1.Name=sAccountName;
                      PelcoAccountLst.add(PelAcc1);
                      insert PelcoAccountLst;  
                  }//closing if for iPelAccnt1 
             }//end if
        }//end if 
             
     }//closing forLoop
 }//closing trigger updateOpptyAccount

The test class is 
@istest
private class TestUpdateOptyAccount {
    static testMethod void TestOptyUpdate() {
        //Create Account
        Account a = new Account();
    	a.Name = 'Ritzy';
    	insert a;
        
        //Create Opportunity
        Opportunity opty=new Opportunity();
		opty.Name='Test Opportunity';
        opty.StageName='Prospecting';
        opty.CloseDate=date.valueof('2015-09-10');
        opty.AccountId=a.Id;
        //opty.Pelco_Account_Name__c=PA.id;
		Insert opty; 
        
        //Create pelco account
        Pelco_Account__c PA =new Pelco_Account__c();
        PA.Name='Ritzy';
        //PA.OpportunityId=Opty.id; 
        PA.AccountName__c=a.Id;
        PA.OpportunityName__c=Opty.id;
        Insert PA;
         //Insert Quote
        Quote q =new Quote();
         q.name='Test Quote';
         q.opportunityId=opty.id;
        insert q;
        
    }
}

The trigger is failing with error message :
System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, updateOpptyAccount: execution of BeforeInsert

caused by: System.QueryException: List has no rows for assignment to SObject

Trigger.updateOpptyAccount: line 14, column 1: []
I just inserted a record. why would system complain that I have no rows for assignment to SObject i.e. Quote

Line 14 is 
QuoteInLoop.Pricebook2Id =[SELECT Id FROM Pricebook2 WHERE Name = 'Standard Price Book' LIMIT 1].Id;


 
Best Answer chosen by Gaurav Agnihotri
Amit Chaudhary 8Amit Chaudhary 8
Please try to add account lookup on Quote object. I hope that will resolve ur issue


//Insert
Quote Quote q =new Quote();
q.name='Test Quote';
q.opportunityId=opty.id;
q.accountid=a.id;
insert q;

Please let us know if this will help you

Thanks
Amit Chaudhary

All Answers

Gaurav AgnihotriGaurav Agnihotri
The error was corrected by inserting Pricebook2 in test script.
Pricebook2 pb=new Pricebook2();
        pb.IsActive=true;
        pb.Name='test';
        insert pb;
The code coverage is 54%
code not covered
SaranSaran
Hi Gaurav,

You can use this also if it help you to resolve.
 
Id stdPricebookId;
        if(!test.isRunningtest()){
            stdPricebookId = [SELECT id FROM Pricebook2 WHERE IsStandard = :true AND Name = 'Standard Price Book' limit 1].id;      
        }
        else{
            stdPricebookId = Test.getStandardPriceBookId();        
        }

Hope this might help you to solve your issue.

FYI,
You have used query and insert statement inside the for loop. So in insert of bulk data you may get any dml and query limit exception. Try to avoid using the query and dml inside the loop.

Also instead of assigning everything to a string and check it as null or not. You can directly use quoteLoop.FieldName != null.

Thanks,
Amit Chaudhary 8Amit Chaudhary 8
Please try to add account lookup on Quote object. I hope that will resolve ur issue


//Insert
Quote Quote q =new Quote();
q.name='Test Quote';
q.opportunityId=opty.id;
q.accountid=a.id;
insert q;

Please let us know if this will help you

Thanks
Amit Chaudhary
This was selected as the best answer
Gaurav AgnihotriGaurav Agnihotri
Hi Amit, 
accountId is  lookup field, so I cannot update it. I am striving to get a better code coverage. My current code coverage is 54%

Following lines are not covered:
User-added image

 
SaranSaran
Hi  Gaurav,

Try this,
 
Quote q =new Quote();
	q.name='Test Quote';
	q.opportunityId=opty.id;
	q.Pelco_Account_Name__c = PA.id;
	insert q;

Hope this might help you!!

Thanks
Gaurav AgnihotriGaurav Agnihotri
Hi Saran, 
I used your suggestion. I am able to get 91% code coverage. 
Thanks for reminding me not to use query and insert statement in for loop. If I find time, I will redesign the trigger.
Gaurav AgnihotriGaurav Agnihotri
Thanks Amits and Saran, 
I was able to get 100% code coverage.