+ Start a Discussion
sermetegesermetege 

Testing for VF Controller

My Controller : 
Controller
My Test:
User-added image

I want to write test for my controller but i can't. Can anyone help for this? Regards :)

Best Answer chosen by sermetege
Peter_sfdcPeter_sfdc
Sermetege, I can think of a couple of things that would improve your test method. 

As philip.southern states, you definitely need to create some contacts in order for your query to return any results. 

A couple of other things I would suggest as you appear to be new to this: 
  1. Don't query if you don't have to. Your standard controller doesn't actually require a contact record, and yet you are retrieving one by querying in your test method (a bad practice anyway). Just create an empty instance of Contact instead. 
  2. Your use of Test.startTest() is misplaced. These are just about separating governor limit context, so should really stick those only around the method or logic that is the focus of your test. 
  3. Perhaps most importantly: assert a behavior. Without an assert, you do not have a test. 
public static testMethod void myTest(){

  Contact cont = new Contact(); //(unless you actually need something, don't bother)

  Account acct = new Account(name='Sochi Olympic Committee');
  insert acct; 

  List<Contact> contacts = new List<Contact>();

  for (Integer i = 0 ; i < 50 ; i ++) {
    contacts.add(new Contact(FirstName='Vladimir',LastName='Putin' + i,Email='vlad@sochi.ru',AccountId=acct.id));
  }
  insert contacts;
  
  //not a bad idea to assert the test is setup correctly
  System.assertEquals(50, [select Id from Contact].size(), 'the test case was not setup with the correct number of 50 records');

  PageReference myPage = Page.SearchBill;
  Test.setCurrentPage(myPage);
  ApexPages.StandardController sc = new ApexPages.StandardController(cont); 
  SearchBillController sbc = new SearchBillController(sc); 
  
  //let's test the constructor did what it is supposed to do...we have 50 contacts in the db, but the controller limits to 20
  System.assertEquals(20, sbc.cont.size(), 'the constructor did not return the expected number of contact records')
  
  //let's actually test something meaningful
  sbc.searchInput = 'Putin1'; //there should be 11 of these in the db: Putin1, Putin10-19)
  sbc.find();
  System.assertEquals(11, sbc.cont.size, 'after invoking the search, the conroller did not retrieve the expected number of records');

}


This should give you a better test structure. This also reflects some of the preferences I've come to develop in my test methods:
  • I didn't bother with Test.start/stopTest() in this instance. I don't find it necessary in this kind of light weight test. It is really better in large bulk tests where you are pushing the limits either in your data setup or your actual tested logic. Also, when doing an end-to-end test like this there are several tested actions and you only get one startTest and stop Test per test method
  • I always like to use the third parameter of the assert method which allows me to explain what this test was meant to do for whoever runs the test.
Finally, you really might think about a final test of the actual data in the list that is retrieved...something like looping through sbc.cont and making sure you have the actual contact records you searched for. 

(One last request. Even though it is easier to read, I would suggest posting your code as text next time as it is a lot easier to copy and past something than hand copying a screen shot. Screen shots are great for showing UI and error messages. Thanks)

All Answers

Phillip SouthernPhillip Southern
Hi, in your test class you need to create some contacts so the controller can pick them up.  So right after you start the test, just create some contacts on the fly and insert them....etc:

account a = new  account(name='test');
insert a;
contact c = new contact(accountid=a.Id,lastname='test',);
insert c;

Also remove the soql from your test class...you won't need that.
Peter_sfdcPeter_sfdc
Sermetege, I can think of a couple of things that would improve your test method. 

As philip.southern states, you definitely need to create some contacts in order for your query to return any results. 

A couple of other things I would suggest as you appear to be new to this: 
  1. Don't query if you don't have to. Your standard controller doesn't actually require a contact record, and yet you are retrieving one by querying in your test method (a bad practice anyway). Just create an empty instance of Contact instead. 
  2. Your use of Test.startTest() is misplaced. These are just about separating governor limit context, so should really stick those only around the method or logic that is the focus of your test. 
  3. Perhaps most importantly: assert a behavior. Without an assert, you do not have a test. 
public static testMethod void myTest(){

  Contact cont = new Contact(); //(unless you actually need something, don't bother)

  Account acct = new Account(name='Sochi Olympic Committee');
  insert acct; 

  List<Contact> contacts = new List<Contact>();

  for (Integer i = 0 ; i < 50 ; i ++) {
    contacts.add(new Contact(FirstName='Vladimir',LastName='Putin' + i,Email='vlad@sochi.ru',AccountId=acct.id));
  }
  insert contacts;
  
  //not a bad idea to assert the test is setup correctly
  System.assertEquals(50, [select Id from Contact].size(), 'the test case was not setup with the correct number of 50 records');

  PageReference myPage = Page.SearchBill;
  Test.setCurrentPage(myPage);
  ApexPages.StandardController sc = new ApexPages.StandardController(cont); 
  SearchBillController sbc = new SearchBillController(sc); 
  
  //let's test the constructor did what it is supposed to do...we have 50 contacts in the db, but the controller limits to 20
  System.assertEquals(20, sbc.cont.size(), 'the constructor did not return the expected number of contact records')
  
  //let's actually test something meaningful
  sbc.searchInput = 'Putin1'; //there should be 11 of these in the db: Putin1, Putin10-19)
  sbc.find();
  System.assertEquals(11, sbc.cont.size, 'after invoking the search, the conroller did not retrieve the expected number of records');

}


This should give you a better test structure. This also reflects some of the preferences I've come to develop in my test methods:
  • I didn't bother with Test.start/stopTest() in this instance. I don't find it necessary in this kind of light weight test. It is really better in large bulk tests where you are pushing the limits either in your data setup or your actual tested logic. Also, when doing an end-to-end test like this there are several tested actions and you only get one startTest and stop Test per test method
  • I always like to use the third parameter of the assert method which allows me to explain what this test was meant to do for whoever runs the test.
Finally, you really might think about a final test of the actual data in the list that is retrieved...something like looping through sbc.cont and making sure you have the actual contact records you searched for. 

(One last request. Even though it is easier to read, I would suggest posting your code as text next time as it is a lot easier to copy and past something than hand copying a screen shot. Screen shots are great for showing UI and error messages. Thanks)

This was selected as the best answer
sermetegesermetege

Thank you so much!!!  My code passed the test with %88.

I also wonder the reason of red area. What could be the reason for this problem?

User-added image