+ Start a Discussion
Lee.ax1423Lee.ax1423 

Problem with test cases...

Can any one help me for writing test cases for following code.. I have written something but it is not entering in for loop.

code here....

 

private List<Contact> acc;
public String Combination = '';

public MyClass(ApexPages.StandardSetController controller) {
acc = (List<contact>)controller.getSelected();
for (contact ac:acc){
if(ac.MobilePhone != null){
Combination = ac.MobilePhone+','+Combination;
}else{
Combination = '';
break;
}}}
 

Thanks,

Best Answer chosen by Admin (Salesforce Developers) 
vishal@forcevishal@force

You're not getting any results because of this :

 

acc = (List<contact>)controller.getSelected();

 


Maybe not ideal, but a very simple way to handle this would be:

 

if(!Test.isRunningTest())

{

     acc = (List<contact>)controller.getSelected();

}

else

{

     acc = [Select MobilePhone From Contact Limit 1];

}

 


And to ensure the query ([Select MobilePhone From Contact Limit 1]) returns you one row:

 

Create 2 contacts, one with MobilePhone blank and one with some MobilePhone Number in your test class. Call your constructor after each creation so that it covers the if, else loop inside the for.

 

 

All Answers

SamuelDeRyckeSamuelDeRycke

Would you mind showing what you have writen so far ?

 

If it is not entering the for loop, that is because your query may not give any results while testing. Since API 24 there test code has no data access unless specified so for most object types  ( see:  http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_data_access.htm ). This is to minimize code dependency on existing records (which may at some point be edited or deleted).

 If you insert some contacts at the start of your test method your problem should be resolved. As you have conditional logic on the mobilephone field, you may want to have one contact having a value in that field, and another contactt not having a value in that field, so that both branches are covered in your test method.

 

 

 

vishal@forcevishal@force

You're not getting any results because of this :

 

acc = (List<contact>)controller.getSelected();

 


Maybe not ideal, but a very simple way to handle this would be:

 

if(!Test.isRunningTest())

{

     acc = (List<contact>)controller.getSelected();

}

else

{

     acc = [Select MobilePhone From Contact Limit 1];

}

 


And to ensure the query ([Select MobilePhone From Contact Limit 1]) returns you one row:

 

Create 2 contacts, one with MobilePhone blank and one with some MobilePhone Number in your test class. Call your constructor after each creation so that it covers the if, else loop inside the for.

 

 

This was selected as the best answer
bvramkumarbvramkumar

In your test coverage code, Are you creating contacts to be passed in through the StandardsetController?

 

In your test coverage code, do the below:

1. Create a contact record.

2. Then create an instance of ApexPages.StandardSetController. call the instance stdSetCtlr

3. Use the setSelected() method of stdSetCtlr. stdSetCtlr.set(new List<Contact>{<Contact record you created in step 1});

4. Now call your class's constructor by passing the stdSetCtlr.

 

As you have set the selected contacts before calling constructor, the getSelected() method should return you more than 1 record  and is supposed to enter that for loop. Check the documentation http://www.salesforce.com/us/developer/docs/pages/Content/apex_pages_standardsetcontroller.htm

Lee.ax1423Lee.ax1423

Ya Thanks vishal it's working great.........

bvramkumarbvramkumar

Lee. In Vishal's approach, the else part he did like below:

 

else

{

     acc = [Select MobilePhone From Contact Limit 1];

}

 

This is not a best practice and you coverage will fail again if your production/sandbox does not have any contacts. Think again.

SamuelDeRyckeSamuelDeRycke

I agree with bvramkumar

 

Please post your entire test code so we can help you most appropriately. Having different code executed when testing is bad practise in 99% of the cases if you ask me. It contradicts the purpose of testing your code, as you are just running differnt code. 

 

The reason we should write test code, and verify our code does what we expect is not because some funny men made some rules to make it hard to develop stuff. It is to protect ourselves and our customers/users against our mistakes by catching them early. Testing your developtment is as crucial as your development itself.

 

 

Lee.ax1423Lee.ax1423

I am getting little bit .Actually i have achieved 75% coverage.But still I am in confusing what you people are saying.This is my class....

 

public class quickEmailController{
private List<Contact> acc;
public String Combination;
public quickEmailController(ApexPages.StandardsetController controller)
{
if(!Test.isRunningTest()){
acc = (List<contact>)controller.getSelected();
}else
{
     acc = [Select mobilephone From Contact Limit 1];
}
for (contact ac:acc){
            if(ac.mobilephone != null){
                Combination = ac.MobilePhone+','+Combination;
                }else{
                Combination = '';
               break; }}}
 Public PageReference dosomething(){
     if (Combination != '') {
             if(acc.size() <150){
                    //do something}
            }return null;
}}

 

Test class:-

@isTest
public class testquickcontroller{
static testmethod void testmehod1(){
contact[] cc=new contact[]{
new contact(lastname='prasad',mobilephone='12345'),new contact(lastname='hello',mobilephone='123')};
insert cc;
ApexPages.StandardsetController strcontroller = new ApexPages.StandardsetController(cc);
quickEmailController qcc = new quickEmailController(strcontroller);
qcc.dosomething();
system.assert(cc[0].mobilephone != null);
}}

 

Thanks,

Lee

vishal@forcevishal@force

If you read the post again, I have clearly mentioned that he needs to create 2 contacts so that he doesn't need to depend on data in the Production Org. If that is done, I don't see him facing any issues with the shared approach.

SamuelDeRyckeSamuelDeRycke

Before getting into your test code, I need to ask

 

 for (contact ac: acc) {
        //are you sure about this logic ? 
            if (ac.mobilephone != null) {
                Combination = ac.MobilePhone + ',' + Combination;
            } else {
                Combination = '';
                break;
            }
 }

 What are you trying to do ?  With this implementation, on every contact having no mobile phone you'll reset your Combination string to ' '.  I can be wrong, but is this what you're trying to do ?

 

 for (contact ac: acc) {
            if (ac.mobilephone != null) {
                Combination +=  ac.MobilePhone + ',';
            }
            Combination = Combination.ubstring(0,Combination.length()-1);
}

 Just wondering, because your own implementated logic would give very unpredictable results, so is a bit harder to test.