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
IGateIGate 

Test Class code coverage

public class abcd
     {
      public void m1()
      {
      Attachment myAttach = new Attachment();
      myAttach.ParentId = '001900000063kAB';//Id of the object to which the page is attached
      myAttach.name = 'attachment';
      PageReference myPdf = Page.one;//myPdfPage is the name of your pdf page
      myAttach.body = myPdf.getContentAsPdf();
      insert myattach;  
      }
      
      static testmethod void testm1()
      {
          abcd obj1=new abcd();
          obj1.m1();
      }
     }

 

Hi how can i conver the red marked line.



Best Answer chosen by Admin (Salesforce Developers) 
SteveBowerSteveBower

Well the short answer is to insert a line:         obj.val = 'Account';    before you call getNames.

 

The longer answer is

1. Use comments.  It's hard to figure out what you're trying to do and there may be easier ways to do it.

2. It looks like you're trying to take an Object name and create a picklist of the Fields names of that object.  Why?  What's your business goal in this, there may be far easier ways to accomplish it.

3. How are you going to check if your SelectOptions list has been correctly filled?   Are you checking it after calling obj.getNames or are you just hoping that it's correct?

 

As an aside this code seems to do the same thing your code does (unless your intent is just to trim out Namespace)? 

Map<String, Schema.SObjectField> objectFields = Schema.getGlobalDescribe().get(val).getDescribe().fields.getMap();

for(String s : objectFields.keySet())

      if (s.contains('__c'))  options.add(new selectOption(s, s))

 

 

 

 

4. You need to decide if your purpose in writing test code is to just reach some level of code coverage, or if it's to see if the code *actually worked*.

 

For example:

 

public class Millionaire() {

String bingo;

 

        public void setSalaryToMillionaire() {

                Contact C = [select id, name from account where name = :bingo];

                C.Salary = '1000000.00';    // Bingo!!!

                update C;

                return;

        }

}

 

Your test case is sort of equivalent to:

 

static testMethod void testMillionaire() {

       Millionaire M = new Millionaire();

       M.setSalaryToMillionair();

}

 

Now, that may or may not give you sufficient code coverage to pass.  But you haven't actually tested anything, so it's crap.  Garbage.

Who knows, perhaps there is a validation rule on Contact that says Salary can't be greater than 200,000.   In either case, you didn't assign a value to "bingo" and so it didn't return any records, so no update was done, etc.  

 

Versus: 

 

static testMethod void testMillionaire() {

       Contact C = new Contact (Name='Fred', Salary=0.0);

       insert C;

       Millionaire M = new Millionaire();

       M.bingo = 'Fred';

       M.setSalaryToMillionaire();

       C = [select Salary from Contact where id=:C.id];

       system.assertEquals(1000000, C.Salary);

}

 

This is better, but it still doesn't test the wider cases..

 

 

 

static testMethod void testMillionaire() {

       Contact C = new Contact (Name='Fred', Salary=0.0);

       insert C;

       Millionaire M = new Millionaire();

       M.bingo = 'Fred';

       M.setSalaryToMillionaire();

       C = [select Salary from Contact where id=:C.id];

       system.assertEquals(1000000, C.Salary);

 

       M.bingo='No User With This Name';

       M.setSalaryToMillionaire();

       // This will cause your class above to crash because no Contact would be found with that name, but you aren't checking for that in the code above.  So, you'll have to go back and add error checking for the results of the search.

}

 

 

So, I'm writing all this because I'm trying to point out that just trying to get code coverage is a waste of time.   Instead take care of getting functionality, check the results, and then the coverage will take care of itself, and you may have to write more code anyway.

 

Best, Steve.

 

 

 

 

All Answers

SteveBowerSteveBower

 

Why isn't it being covered?  You code has no branching or returns so if everything were working properly it would go through each line of code and you'd get 100% coverage.  

 

So something isn't working correctly, what is it?   What does the error log say?   I'd guess that your getContentAsPdf call is failing, probably because you haven't passed the VF page an Id.

 

Consider adding some error catching code.  Try/Catch blocks, perhaps some system.asserts in your test code... you know, just for fun.  :-)

 

Best, Steve

 

P.S. If you don't really care if the document gets attached to the parent (because you're not testing for it, so I assume you don't care), you could always just comment out the Insert statement and get the coverage that way!

 

 

 

IGateIGate

Hi Steve, Thank u so much.

Please  solve this test class.

public class allobjcon 
{
    public String pickname { get; set; }
        Map<String, Schema.SObjectField> M = Schema.SObjectType.Account.fields.getMap();
        public List<selectOption> getNames()
        {
                    List<selectOption> options=new List<selectOption>();
                    List<String> fieldLabels=new List<String>();
                    Map<String,String> fieldLabelNameMap=new Map<String,String>();
                    Boolean evaluateFields=False;
                    system.debug(val);
                    if(val!=null){
                    SObjectType objToken = Schema.getGlobalDescribe().get(val);
                    DescribeSObjectResult objDef = objToken.getDescribe();
                    Map<String, SObjectField> fieldMap = objDef.fields.getMap();
                    system.debug(fieldMap);
                    system.debug(fieldMap.keySet());
                    options.add(new selectOption('','-select one-'));
                    for (String fName:fieldMap.keySet()){
                    if(fieldMap.get(fName).getDescribe().getLocalName().contains('__c'))
                    {
                    fieldLabels.add(fieldMap.get(fName).getDescribe().getlocalName());
                    fieldLabelNameMap.put(fieldMap.get(fName).getDescribe().getlocalName(), fName);
                    }
                    }
                    fieldLabels.sort();
                    for (String fLabel:fieldLabels){
                    options.add(new selectOption(fieldLabelNameMap.get(fLabel),fLabel));
                    }
                    }
                    return options;
        }
        public String val { get; set; }
        
        static testmethod void testm1()
        {
            allobjcon obj=new allobjcon();
            obj.getNames();
          
        }

 

The red marked code is not coverting in my test class.

please give a suggestion

 

 

My OwnMy Own

 

 

set the value for "val"  in the test method.

 



 static testmethod void testm1()
        {
            allobjcon obj=new allobjcon();
            obj.val = 'your object name/field name';  //
            obj.getNames();
          
        }

 

SteveBowerSteveBower

Well the short answer is to insert a line:         obj.val = 'Account';    before you call getNames.

 

The longer answer is

1. Use comments.  It's hard to figure out what you're trying to do and there may be easier ways to do it.

2. It looks like you're trying to take an Object name and create a picklist of the Fields names of that object.  Why?  What's your business goal in this, there may be far easier ways to accomplish it.

3. How are you going to check if your SelectOptions list has been correctly filled?   Are you checking it after calling obj.getNames or are you just hoping that it's correct?

 

As an aside this code seems to do the same thing your code does (unless your intent is just to trim out Namespace)? 

Map<String, Schema.SObjectField> objectFields = Schema.getGlobalDescribe().get(val).getDescribe().fields.getMap();

for(String s : objectFields.keySet())

      if (s.contains('__c'))  options.add(new selectOption(s, s))

 

 

 

 

4. You need to decide if your purpose in writing test code is to just reach some level of code coverage, or if it's to see if the code *actually worked*.

 

For example:

 

public class Millionaire() {

String bingo;

 

        public void setSalaryToMillionaire() {

                Contact C = [select id, name from account where name = :bingo];

                C.Salary = '1000000.00';    // Bingo!!!

                update C;

                return;

        }

}

 

Your test case is sort of equivalent to:

 

static testMethod void testMillionaire() {

       Millionaire M = new Millionaire();

       M.setSalaryToMillionair();

}

 

Now, that may or may not give you sufficient code coverage to pass.  But you haven't actually tested anything, so it's crap.  Garbage.

Who knows, perhaps there is a validation rule on Contact that says Salary can't be greater than 200,000.   In either case, you didn't assign a value to "bingo" and so it didn't return any records, so no update was done, etc.  

 

Versus: 

 

static testMethod void testMillionaire() {

       Contact C = new Contact (Name='Fred', Salary=0.0);

       insert C;

       Millionaire M = new Millionaire();

       M.bingo = 'Fred';

       M.setSalaryToMillionaire();

       C = [select Salary from Contact where id=:C.id];

       system.assertEquals(1000000, C.Salary);

}

 

This is better, but it still doesn't test the wider cases..

 

 

 

static testMethod void testMillionaire() {

       Contact C = new Contact (Name='Fred', Salary=0.0);

       insert C;

       Millionaire M = new Millionaire();

       M.bingo = 'Fred';

       M.setSalaryToMillionaire();

       C = [select Salary from Contact where id=:C.id];

       system.assertEquals(1000000, C.Salary);

 

       M.bingo='No User With This Name';

       M.setSalaryToMillionaire();

       // This will cause your class above to crash because no Contact would be found with that name, but you aren't checking for that in the code above.  So, you'll have to go back and add error checking for the results of the search.

}

 

 

So, I'm writing all this because I'm trying to point out that just trying to get code coverage is a waste of time.   Instead take care of getting functionality, check the results, and then the coverage will take care of itself, and you may have to write more code anyway.

 

Best, Steve.

 

 

 

 

This was selected as the best answer
IGateIGate

Hi steve, thank u so much.

The code coverage for below class is 100%.

But i am thinking there is no need of calling each method in batch apex class.

Without calling each method how can i write the test class.

 

Please reply your answer.

-----------------------

 

global class batchsample1 implements Database.Batchable<sObject>
{    
    global integer i;    
     global Database.QueryLocator start(Database.BatchableContext bc)
    {       
          return Database.getQueryLocator('select Id,Name from x__c');   
    }           
    global void execute(Database.BatchableContext bc,List<x__c> lstAccount)
    {        
          List<x__c> lstaccountUpdate = new List<x__c>();
           lstaccount=[select id,name from x__c];
          
     for(integer j=0;j<lstAccount.size();j++){
             lstAccount[j].name = 'Test' + string.valueOf(j);
             lstaccountUpdate.add(lstAccount[j]);
     }
     system.debug('lstaccountUpdate'+lstaccountUpdate.size());
     update lstaccountUpdate;            
     }      
    global void finish(Database.BatchableContext bc)
    {      
         system.debug('all done.');   
    }
    
    static testmethod void testm1()
    {
       
        Test.startTest();
        batchsample1 obj=new batchsample1 ();
        Database.BatchableContext bc;
        obj.start(bc);
        List<x__c> lstone=new List<x__c>();
        obj.execute(bc,lstone);
        obj.finish(bc);
        Test.stopTest();
    }
}

 

 

Here is my test class. But how can i cover my code using database.executebatch(obj);

 

SteveBowerSteveBower

Sorry, I don't know what you're asking. Have you read the page in the Apex doc on Batch, and

the sample code on testing it?

 

Best, Steve.

 

 

Also, people normally try to keep to one topic per thread.

 

Also, your 100% code coverage is crap.

 

Nowhere do you test to see if any of the x__c records have been updated to have "Test" in their names after you make the batch call. And you're not inserting any x__c records before the test

so you can compare them after the call.

 

You have no idea if your code works or not.

IGateIGate

Hi Steve,

Thanku so much.

 

global class batchsample1 implements Database.Batc

hable<sObject>
{    
    global integer i;    
     global Database.QueryLocator start(Database.BatchableContext bc)
    {       
          return Database.getQueryLocator('select Id,Name from x__c');   
    }           
    global void execute(Database.BatchableContext bc,List<x__c> lstAccount)
    {        
          List<x__c> lstaccountUpdate = new List<x__c>();
           lstaccount=[select id,name from x__c];
          
     for(integer j=0;j<lstAccount.size();j++){
             lstAccount[j].name = 'Test' + string.valueOf(j);
             lstaccountUpdate.add(lstAccount[j]);
     }
     system.debug('lstaccountUpdate'+lstaccountUpdate.size());
     update lstaccountUpdate;            
     }      
    global void finish(Database.BatchableContext bc)
    {      
         system.debug('all done.');   
    }

 

 static testmethod void testm1()

{

/////////Please  Write the test class code in this place

}

}

Can you please give the test class for this batch apex class.