This code works fine but the code coverage is only 84%. How can I reach 100% ? and also help to add logic to the code. Logic to be added is: there a picklist field called competitor machine and a text field called description.

condition:if competitor machine=other and description= null then it has to fire an error message.


public with sharing class ctrlCompetitor { 
    public static Integer flag=0; 

 public Competitor__c cc{get;set;} 
    public Competitor__c cc1=new Competitor__c(); 
    public List<Competitor__c> listComptr=new List<Competitor__c>();  
    public ctrlCompetitor(){}

    //extension invoked to pre-populate the Name parameter
    public ctrlCompetitor(ApexPages.StandardController stdController) {  
       cc=new Competitor__c();      
       cc = (Competitor__c)stdController.getRecord(); 
     catch(Exception e){System.debug(e.getMessage());}

   //cache all the primary competitors for the particular opportunity
   public void init(){      
    listComptr=[SELECT Id,Name,Primary_Competitor__c from Competitor__c where 
                                 Opportunity__r.Id =:ApexPages.currentPage().getParameters().get('retURL').substring(1,16) AND Primary_Competitor__c=true];     

   //method to uncheck the primary competitor for other competitor records     
   public static void checkPrimaryComp(String oppId){              
    Map<Id,Competitor__c> compMap=new Map<Id,Competitor__c>([SELECT Id,Name,Primary_Competitor__c from Competitor__c where Opportunity__r.Id =: 
     for(Competitor__c comp : compMap.values()){         
     update compMap.values();      

   //invoked to check for the first primary competitor
   public static String checkFirstPrimaryComp(String oppId){
   List<Competitor__c> listTemp=[SELECT Id,Name,Primary_Competitor__c from Competitor__c where 
                                 Opportunity__r.Id =:oppId.substring(1,16) AND Primary_Competitor__c=true];
       if(listTemp.size()==0){return 'true';}
       else{return 'false';}   


   //method invoked on update of Competitor records
   public void onUpdatePrimaryComp(){
     if(Trigger.IsUpdate && !Trigger.IsInsert && flag==0){
     SET<Id> oppIds=new SET<Id>();          
     for(Sobject sobj: Trigger.new){
        Competitor__c cc1=(Competitor__c)sobj;
     List<Competitor__c> listTemp=[SELECT Id,Name,Primary_Competitor__c,Opportunity__r.Id from Competitor__c where Opportunity__r.Id in : oppIds AND
                               Primary_Competitor__c=true] ;        
         for(Sobject sobj: Trigger.new){
             Competitor__c cc1=(Competitor__c)sobj;

                 for(Integer i=0;i<listTemp.size();i++){
                     if(listTemp.get(i).Opportunity__r.Id == cc1.Opportunity__c){
       update listTemp;}     
     catch(Exception e){System.debug('==Exception Message==='+e.getMessage());}

    //method invoked to save and return to the original Opportunity record Page
    public PageReference Save(){

      insert cc;
      update cc;
      catch(Exception e){}        
      return new PageReference('/'+ApexPages.currentPage().getParameters().get('retURL').substring(1,16));

    //method is invoked on click of CANCEL button
    public PageReference Cancel(){
      update listComptr;
    catch(Exception e){
      System.debug('==Exception Message==='+e.getMessage());
     return new PageReference('/'+ApexPages.currentPage().getParameters().get('retURL').substring(1,16));



Test Class:

public class ctrlCompetitor_UT{

    public static testMethod void testPrimaryComp(){
    Account acc=new Account(name='testacc',BillingCountry='CA', BillingState='British Columbia',
                            ShippingCountry='CA', ShippingState='British Columbia');
    insert acc;
    Opportunity opp = new Opportunity (account = acc, name='testOpp', stagename='target', closeDate=Date.Today(), CurrencyIsoCode='USD');
    insert opp;
    Competitor__c c1=new Competitor__c(Name='Test Competitor',Primary_Competitor__c=false,Opportunity__c=opp.Id);
    insert c1;
    Competitor__c c2=new Competitor__c(Name='Test Competitor2',Primary_Competitor__c=true,Opportunity__c=opp.Id);
    insert c2;
    Competitor__c c3=new Competitor__c(Name='Test Competitor3',Primary_Competitor__c=false,Opportunity__c=opp.Id);
    insert c3;   
    ApexPages.currentPage().getParameters().put('Name', 'Test Competitor');
    ApexPages.currentPage().getParameters().put('retUrl', '/'+opp.Id);    
    ApexPages.StandardController app=new ApexPages.StandardController(c1);
    ctrlCompetitor cc=new ctrlCompetitor(app);
    update c1;
  • Welcome to SFSE. You're asking two different questions so I would suggest posting the logic part separately. Also, you don't indicate which lines are not covered by your tests; can you add that? It'll help us give you pointers.
    – Mike Chale
    Dec 18, 2013 at 13:33

1 Answer 1


With regards the code coverage. Personally, I feel seeking code coverage (and only code coverage) is the wrong approach to unit tests. You can have perfectly sound tests that are not always achieving 100% coverage and conversely bad unit tests that do achieve 100%.

Think for a minute about what you are trying to achieve when you are writing your unit tests, you're actually trying to make sure that your code is robust and will not fail in your production environment. You're also trying to ensure that your code does what you want it to. Looking at your test class, I don't see any evidence that you are testing to see that the code does what you expect it to.

I can see in your code that you are inserting and updating some records, in my view you should be checking in your test that this is actually the case, and the values that are inserted are correct. In my opinion, you should consider using the System.assert* methods to check that your code has done what you expect it to rather than chasing 100% coverage.

  • 1
    Tidbit: If you're going in for a security review, they expect asserts to make sure you're testing your logic; they won't deny you, but you will get a stern lecture. The point of unit tests in any language is to avoid logic bugs, which are errors that a compiler won't catch but will still crash or produce garbage output. The "code coverage requirement" in salesforce is their attempt make you at least think about how the code works at a fundamental level.
    – sfdcfox
    Dec 18, 2013 at 15:19
  • 5
    "Do not try and cover 100%. That's impossible. Instead... only try to realize the truth." "What truth?" "There is no coverage." "There is no coverage?" "Then you'll see, that it is not the code that covers, it is only yourself." -- I've waited a long time to adapt that dialog from Matrix into a smart adage.
    – sfdcfox
    Dec 18, 2013 at 15:22
  • :D Yes, agreed and good point(s). Been a while since I had a stern lecture Dec 18, 2013 at 15:23
  • If you are like a lot of sfdc all singing, all dancing admins, you don't have the 'benefit' of a separate QA department and once you release into PROD, you sort of don't want to do your own smoke tests. Instead, write comprehensive regtests following the suggestions above that verify that your data manipulation is accurate for all the business use cases. It is also worthwhile verifying through regtests that your error handling works correctly and that exceptions are caught and properly displayed with adequate diagnostic info - be they validation errors on sobjects or worse.
    – cropredy
    Dec 20, 2013 at 2:47

You must log in to answer this question.

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