+ Start a Discussion
TechSteveTechSteve 

unit testing code

 

 

Hi all, development in the sandbox doesn't need the testing so been busy developing. The assessment controller is stand alone with no object just a page with direction and display controls. I know I am a pain but could someone help please? with comments please as I am very new. ?

Here's my code so far giving me 63% cover:

@isTest
private class AssessmentcontrollerTest
{
        public static testmethod void AssessmentcontrollerTest()
        {
            Boolean isittrue = true;
            final Boolean istrue = True;
           
            PageReference pageRef =Page.AX; // used to set a page           
            test.setCurrentPage(pageRef);  // set starting page
            ApexPages.CurrentPage().getParameters().put('cid', '003R000000Y7Gw4');
            ApexPages.CurrentPage().getParameters().put('cc', 'True');
           
           
            // instanciate and construct the controller class
            Assessmentcontroller AC = new Assessmentcontroller();
                
                // Instantiate a new controller with all parameters in the page
   
        System.debug('Inserting contact detail(single record validation)');
       
        Contact testrec = new Contact(Is_Client__c = True, LastName = 'notlob', Client_Address_1__c = '1 The Rd',
        Client_County__c = 'somecounty', ContactType__c = 'Client', Client_Town__c = 'Bolton', Client_Postcode__c = 'postcode1',
        Client_DOB__c = System.today());
        insert testrec;
       
        //Validate single insert
   
        for(Contact c:[SELECT Is_Client__c,LastName, Client_Address_1__c,Client_County__c, ContactType__c, Client_Town__c, Client_Postcode__c,
        Client_DOB__c  FROM Contact
            WHERE CreatedDate = TODAY
            and Is_Client__c != null]) {
                isittrue = c.Is_Client__c;
            }
       
        System.assertEquals(isittrue, True);

           }    
         
}

****** Controller *******

public class Assessmentcontroller {

    public String conid { get; private set; }   
    public String notclient { get; private set; }   
    public boolean Notcid { get; private set; }   
    public boolean Nocid { get; private set; }   
    public boolean Gotcid { get; private set; }
     
    public Assessmentcontroller(){
    if(ApexPages.currentPage().getParameters().get('cid')!= null){     
        conid = '?cid='+ApexPages.currentPage().getParameters().get('cid'); //assign client record number to conid
        notclient = ApexPages.currentPage().getParameters().get('cc');
            if (notclient == 'false'){
                Notcid = True;
            }
        Nocid = False;
        Gotcid = True;
        }else{
        Nocid = True;
        Gotcid = False;
        }
    }

    public String Id  { get; private set; }
   
    public ApexPages.StandardSetController setCon {
        get {
            if(setCon == null) {
                Id id = ApexPages.currentPage().getParameters().get('cid');
                setCon = new ApexPages.StandardSetController(Database.getQueryLocator(               
                      [select name, Is_Client__c,Client_DOB__c, Contact_Ref__c, DNR_Authorisation_Uploaded__c from Contact where Id = :id]));
            }
            return setCon;
        }
        set;
    }
    // Initialize setCon and return a list of records     
    public List<Contact> getContacts() {
         return (List<Contact>) setCon.getRecords();
    }
}

Thanks Steve

Best Answer chosen by Admin (Salesforce Developers) 
sfcksfck
Hi,
Don't worry, you'll get there! :)
First of all, the code I gave you was not quite right, for which I apologise! Because getContacts() is a method in the Assessmentcontroller class and you are calling it from within a different class (called AssessmentcontrollerTest), you need to put the object name in front of the method, like this:
   list<contact> the_contacts = AC.getContacts();
  system.assert( the_contacts.size() > 0 ); 

You will probably get "Assertion failed" but that is fine, it just means the contact list is empty and the test has failed. If the test fails you know it's doing something! The next stage would be to look at the test code to make sure it's testing for the right thing. Then if it still fails you know that the real code needs an overhaul.

All Answers

sfcksfck

As far as I can see, you are not using getSetCon() in your test method.

That is probably why you are not getting enough code coverage.

TechSteveTechSteve

Thank you sfck, for your reply.

I am new to all this and am not sure how to go about implementing your suggestion.

I have been looking at the information here and a lot of it is just bits and pieces. Often starting Public static or just static but every time i put that in my code it says top level only can be static. I am lost on that.

Any help on this one would be appreciated.

Thanks again

 

Steve

sfcksfck

Testing is about checking that your code does what it is supposed to do, so you need to think about what you expect to happen when you run the methods in your class.

 

Take the getContacts() method. It returns a list of contacts. If it is working properly, how would you tell? What would the list of contacts be like? And if it was not working properly what would happen? Then test for that in your test method.

 

For example, suppose you know that there should be at least one contact in the list. You can put this in your test to check for that:

 

list<contact> the_contacts = getContacts();

system.assert( the_contacts.size() > 0 );

 

So the assertion will fail if the size of the list that getContacts() returns is zero.

 

By testing the getContacts() method you should get good coverage, because that method also uses the getSetCon() method, so you will be testing that one for free!

 

About the "top level only can be static", I can't help without seeing the code that gets this error.

TechSteveTechSteve

Thanks again sfck, I get what you mean but still get errors! I used your bit of code and put it in mine so it now looks like this

@isTest
private class AssessmentcontrollerTest
{
        public static testmethod void AssessmentcontrollerTest()
        {
            Boolean isittrue = true;
            final Boolean istrue = True;
           
            PageReference pageRef =Page.AX; // used to set a page           
            test.setCurrentPage(pageRef);  // set starting page
            ApexPages.CurrentPage().getParameters().put('cid', '003R000000Y7Gw4');
            ApexPages.CurrentPage().getParameters().put('cc', 'True');
           
           
            // instanciate and construct the controller class
           
            Assessmentcontroller AC = new Assessmentcontroller();

                // Instantiate a new controller with all parameters in the page
   
        System.debug('Inserting contact detail(single record validation)');
        Contact testrec = new Contact(Is_Client__c = True, LastName = 'notlob', Client_Address_1__c = '1 The Rd',
        Client_County__c = 'somecounty', ContactType__c = 'Client', Client_Town__c = 'Bolton', Client_Postcode__c = 'postcode1',
        Client_DOB__c = System.today());
        insert testrec;
       
        //Validate single extract
   
        for(Contact c:[SELECT Is_Client__c,LastName, Client_Address_1__c,Client_County__c, ContactType__c, Client_Town__c, Client_Postcode__c,
        Client_DOB__c  FROM Contact
            WHERE CreatedDate = TODAY
            and Is_Client__c != null limit 1]) {
                isittrue = c.Is_Client__c;
            }
       
        System.assertEquals(isittrue, True);

        list<contact> the_contacts = getContacts();
        system.assert( the_contacts.size() > 0 );
            }    
}

 

But when I try to save it in the editor I get

 Error: Compile Error: Method does not exist or incorrect signature: getContacts() at line 38 column 38

Line 38 being  where your code starts. Do I need to initialise the 'the_contacts'? Am I placing it wrong? Is the GetContacts() incorrect for my code?

Please this is driving me to drink.

Thank you so much for your time.

 

Stev

sfcksfck
Hi,
Don't worry, you'll get there! :)
First of all, the code I gave you was not quite right, for which I apologise! Because getContacts() is a method in the Assessmentcontroller class and you are calling it from within a different class (called AssessmentcontrollerTest), you need to put the object name in front of the method, like this:
   list<contact> the_contacts = AC.getContacts();
  system.assert( the_contacts.size() > 0 ); 

You will probably get "Assertion failed" but that is fine, it just means the contact list is empty and the test has failed. If the test fails you know it's doing something! The next stage would be to look at the test code to make sure it's testing for the right thing. Then if it still fails you know that the real code needs an overhaul.

This was selected as the best answer
TechSteveTechSteve

Thank you so much, that cleared the error and gave me 86% cover on the code. You are a star.

Could you indule me 1 more time please.

The controller in my example is a custom one when i try to construct  the controller on a standard controller I am getting more errors that mean nothing to me. I found an example on a board by yvk431 saying that If its an standard controller, then you need pass the standardcontroller instance as an argument to the contructor before you call it.  giving this code but

 Please ignore this code it is wrong! see below.

Object o = new object();
o.name = 'test';
o.insert;
ApexPages.StandardController stdController = new ApexPages.StandardController(o);
Controller c = new Controller(stdController);

when i tried to use it in my test i get Compile Error: Type cannot be constructed: object. Again the bomb goes off in my brain.

Please if you can help, sorry for taking so much of your time!

Steve

TechSteveTechSteve

might be a bit lost here,

I am using the standard controller in my page but testing an extension.

Does this make a difference to how the above query is approached.

 

Sorry

Steve

sfcksfck

Hi,

 

The main problem is that you are trying to construct an object that is not of any particular type. You are saying "Give me a new Object" but salesforce needs to know what sort of object to create. So you can't just do 

 

Object o = new object();

 

You need to decide what type of object you want, for example you might want a contact so you would do

 

Contact o = new Contact();

o.firstname = 'Bob';

o.lastname = 'Jones';

insert o;

 

(The firstname and lastname are required fields on a contact so you have to set them to something before you insert if you want this example to work. The required fields will be different for different sorts of object).

 

Also it is not "o.insert" but "insert o"

 

Hope that helps

TechSteveTechSteve

Thanks again, IT is noe testing some of my class but is failing with

System.TypeException: Invalid conversion from runtime type SOBJECT:Contact to SOBJECT:INS_Annual_Review__c

referencing the highlighted bit of code            

           public static TestMethod void AnnRevCon2editTest()
        {
            Boolean isittrue = true;
            final Boolean istrue = True;
           
            PageReference pageRef =Page.Annual_Review2e; // used to set a page           
            test.setCurrentPage(pageRef);  // set starting page
            ApexPages.CurrentPage().getParameters().put('cid', '003R000000Y7Gw4');
            ApexPages.CurrentPage().getParameters().put('rid', 'ZZ-100043');
           
                            
                // Instantiate a new controller with all parameters in the page
   
        System.debug('Inserting contact detail(single record validation)');
       
        Contact testrec = new Contact(Is_Client__c = True, LastName = 'notlob', Client_Address_1__c = '1 The Rd',
        Client_County__c = 'somecounty', ContactType__c = 'Client', Client_Town__c = 'Bolton', Client_Postcode__c = 'postcode1',
        Client_DOB__c = System.today());
        insert testrec;
       
        System.debug('Contact detail(single record inserted)');
        //System.assertEquals(Contact.size()>0, True);
        //Validate single insert
   
        for(Contact c:[SELECT Is_Client__c,LastName, Client_Address_1__c,Client_County__c, ContactType__c, Client_Town__c, Client_Postcode__c,
        Client_DOB__c  FROM Contact
            WHERE CreatedDate = TODAY
            and Is_Client__c != null]) {
                isittrue = c.Is_Client__c;
            }
       
        System.assertEquals(isittrue, True);
        system.debug('check isittrue');
    
            ApexPages.StandardController stdController = new ApexPages.StandardController(testrec);       
            AnnRevCon2edit arc = new AnnRevCon2edit(stdController);
        }

without the top highlighted line i get

Compile Error: Variable does not exist: stdController

and without the bottom line it saves ok but doesn't test the AnnRevCon2edit class. with the bottom line only and testrec in place of stdController i get

Compile Error: Constructor not defined: [AnnRevCon2edit].<Constructor>(SOBJECT:Contact) 

Sorry about this but if i can get one working right i should be able to understand more. You have been a marvel so far.

 

Steve

sfcksfck

No problem, happy to have a distraction from work!

 

Could you post the constructor of your AnnRevCon2edit  class?

 

It will be a method that starts

 

"public AnnRevCon2edit"

 

That will help me see what is going on

TechSteveTechSteve

You are a star!!

public class AnnRevCon2edit {

    public String patid { get; set; }
   
    public String conid { get; set; }

    public final INS_Annual_Review__c ar;
  
    ApexPages.StandardController stdCtrl;
   
    public AnnRevCon2edit(ApexPages.StandardController stdController) {
        stdCtrl=stdController;
        this.ar = (INS_Annual_Review__c)stdController.getRecord(); // gets single records from this page.
        ar.ClientID__c = ApexPages.currentPage().getParameters().get('cid'); // assign's cid to ClientID__c
    }
  
    // puts Client info on screen **** working!
    public String Id  { get; private set; } 
 
    // temporary initialisation of contact controller to allow call to info held there.
    public ApexPages.StandardSetController setCon {
        get {
            if(setCon == null) {
                patid = ApexPages.currentPage().getParameters().get('cid'); // loads cid value into patid
                    if(ApexPages.currentPage().getParameters().get('cid')!= null){     
                        conid = '?cid='+ApexPages.currentPage().getParameters().get('cid');
                    }
                Id id = ApexPages.currentPage().getParameters().get('cid');
                setCon = new ApexPages.StandardSetController(Database.getQueryLocator(              
                      [select name, Client_DOB__c, Contact_Ref__c, DNR_Authorisation_Uploaded__c from Contact where Id = :id]));
            }
            return setCon;
        }
        set;
    }

    // Initialize setCon and return a list of records
   
    public List<Contact> getContacts() {
         return (List<Contact>) setCon.getRecords();
    }
    // puts Client info on screen **** working

    //extending the save
      public PageReference saveandnotes() {
          stdCtrl.save(); // This takes care of the details for you.
          PageReference pr = Page.PN;
          pr.getParameters().put('cid',ApexPages.currentPage().getParameters().get('cid'));
          pr.getParameters().put('form','Annual_Review2__c');
          pr.setRedirect(true);
        return pr;
    } 
             
}

 

Cheers mate

sfcksfck



I reckon this line is the problem:

 

this.ar = (INS_Annual_Review__c)stdController.getRecord();

 

When you created the stdController you passed in testrec which is a contact record. So when you do getRecord() it gives you a contact. And in that line you try and convert the contact into an object of type INS_Annual_Review__c, which it is not letting you do.

TechSteveTechSteve

Thanks again sfck,

So do you think I can do without that line or replace it somehow?

Most of these controller are for forms I have recreated in vfpages to make them look as close to the originals as possible. All i am saving in each record is the contact record id number for each contact and then using that to recall the bits I need at the top of each page. So i have to call contact object and the form object in the same page, which I have done but testing that is vexing me.

 

You would appear to be very experienced with this code style any ideas or suggestions would help enormously.

 

Steve

 ps.

 I tried commenting out that line and it seems to work ok but when i run the test it has the same problem causing the fail and the the coverage drops by 2%. don't understand it, do you?

sfcksfck

Hi,


I'm busy now for the evening but what I would suggest to you to think about is: WHY are you trying to turn a Contact object into a annual review or whatever object?  If you are at all confused by the question, then I think what you need is to get into the object oriented way of thinking. WIthout that, apex will be greek to you!


A decent introduction to Java would do fine (apex is very like Java in fact and follows all the same basic principles). You could try this: 

 

http://download.oracle.com/javase/tutorial/java/concepts/


I hope you don't think I'm being patronising, but OOP is a very different way of thinking from other ways of programming, so even if you have done C or whatever before, you may just need a bit of brain-re-organising!

TechSteveTechSteve

Brillant for your help sfck. You have been a great help.

 

Steve