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
jayhunterjayhunter 

Struggling w/ Test Method for my first Controller Extension

I'm fresh out of the DEV501 class, and trying to create my first controller extension and accompanying test class.  I've got the extension done (it's really basic), but I struggled off and on all day yesterday with a test class for the extension.  I've looked at as many examples as I can find, but I can't figure otu how to call the  extension's 1 method from the test class.  It's all very easy stuff I know, I'm hoping someone in the community can spot my error easily.  It shouldn't be tough!  Here's what I've got:

 

public class ProjectBOMPrintoutExtension { public DriveCamProject__c project {get; set;} //This extension does a very simple thing. From a starting DriveCamProject__c, it polls the DB //for any associated project BOM line items that have quantity. These are the line items that //users are interested in when creating a site SO. There's a VF page that uses this list to //build a BOM printout. public List<Project_Product__c> siteBOM { get{ siteBOM = [Select Unit_Price__c, Site_Qty__c, Site_Extended_Amount__c, Part__c, Description__c From Project_Product__c where Project_Name__c=: apexpages.currentPage().getParameters().get('id') and Site_Qty__c > 0 Order by Part__c desc]; return siteBOM; } set;//not sure if we need a setter, but putting it in for now } public ProjectBOMPrintoutExtension (ApexPages.StandardController stdController){ this.project = (DriveCamProject__c)stdController.getRecord(); } //Test Method public static testMethod void testSiteBOMController() { // Create new Project and BOM line item Account TestAccount = [select id from Account limit 1]; String TestAccountId = TestAccount.Id; RecordType TestRecordType = [select id from RecordType where SobjectType='DriveCamProject__c' limit 1]; String TestRecordTypeId = TestRecordType.id; DriveCamProject__c p = new DriveCamProject__c(Name='Test Project',Account__c= TestAccountId, Status__c='Account Notification', RecordTypeId=TestRecordTypeId); insert p; Project_Product__c pp = new Project_Product__c(Name='Test PP', Project_Name__c = p.id); insert pp; // Get a page reference to our newly created project PageReference pg1 = new PageReference('/apex/ProjectBOMprintout?id='+p.Id); System.test.setCurrentpage(pg1); // TODO: Instantiate the controller (call it "controller") //ApexPages.standardController controller = new ApexPages.standardController(new DriveCamProject__c()); ApexPages.standardController controller = new ApexPages.standardController(p); // TODO: Instantiate the extension (call it "extension") ProjectBOMPrintoutExtension extension = new ProjectBOMPrintoutExtension(controller); // TODO: Instantiate the project from the extension DriveCamProject__c project = extension.project; //p = extension.project; ///!!!!!!!!!!Here's where it goes bad. I just need to call the controller method, but

////!!!!!!!!!I get errors about the method not existing or incorrect sig. // Execute the controller method List<Project_Product__c> BOMList = project.siteBOM(); // Check list isn't null System.assert(BOMList!=null); // Check list is expected size System.assertEquals(1, BOMList.size()); // Check contents of list are as expected System.assertEquals(BOMList[0].id, pp.id);

} }

 

 As I said, I'm sure this is easy stuff.   It's almost embarrassing posting something so simple, but I'm stuck.

 

Best Answer chosen by Admin (Salesforce Developers) 
WesNolte__cWesNolte__c

Hey Mr J

 

You're almost there. Change this,

 

List<Project_Product__c> BOMList = project.siteBOM();

 

to this,

 

List<Project_Product__c> BOMList = extension.siteBOM; // I've removed the parenthesis

 

When you use the get; and set; directives you're not defining a method, but something a little bit different called a property. They're a convenient way to defined getters and setters for methods.. basically shorthand for getSiteBom() and setSiteBom() ( which are actual methods ) and need the '()'.

 

Just a heads up on testing, you should try to not rely on any data currently in your Org when testing because when you deploy the code to another environment, you aren't always guarenteed the data will be the same i.e. create your own records with 'insert' at the beginning of the test method (don't worry, the data will only exist for the lifetime of the test method execution).

 

Hope that helps,

Wes 

Message Edited by weznolte on 01-22-2010 04:31 PM

All Answers

bob_buzzardbob_buzzard

In this line: 

 

List<Project_Product__c> BOMList = project.siteBOM();

 

you are attempting to execute the controller method siteBOM() on a DriveCamProject__c sObject called project.

 

It looks to me like you should be doing:

 

 List<Project_Product__c> BOMList = extension.siteBOM();

WesNolte__cWesNolte__c

Hey Mr J

 

You're almost there. Change this,

 

List<Project_Product__c> BOMList = project.siteBOM();

 

to this,

 

List<Project_Product__c> BOMList = extension.siteBOM; // I've removed the parenthesis

 

When you use the get; and set; directives you're not defining a method, but something a little bit different called a property. They're a convenient way to defined getters and setters for methods.. basically shorthand for getSiteBom() and setSiteBom() ( which are actual methods ) and need the '()'.

 

Just a heads up on testing, you should try to not rely on any data currently in your Org when testing because when you deploy the code to another environment, you aren't always guarenteed the data will be the same i.e. create your own records with 'insert' at the beginning of the test method (don't worry, the data will only exist for the lifetime of the test method execution).

 

Hope that helps,

Wes 

Message Edited by weznolte on 01-22-2010 04:31 PM
This was selected as the best answer
bob_buzzardbob_buzzard
Spotters badge for the parenthesis Wez.
jayhunterjayhunter

Excellent advice, many thanks for the assist!  Code is working and tests with 100% coverage now.  Only problem now is one of my asserts is failing:

 

// Check list is expected size System.debug('**********List Size is '+ BOMList.size()); System.assertEquals(1, BOMList.size());

 

My list is zero, so I'm obviously not using the objects I created earlier in the test method (which do get inserted correctly).  I need to invoke the controller/extension with the objects created at the beginning of the test class so I have some results.  I'll start working on that next...

 

 

WesNolte__cWesNolte__c

Hmm.. let's try breaking the code into a few discreet lines:

 

siteBOM = [Select Unit_Price__c, Site_Qty__c, Site_Extended_Amount__c, Part__c, Description__c From Project_Product__c 
where Project_Name__c=: apexpages.currentPage().getParameters().get('id')
and Site_Qty__c > 0
Order by Part__c desc];
return siteBOM;

 becomes:

 

String id = apexpages.currentPage().getParameters().get('id'); // I noticed you had a space between the ':' and apexpages, that might be your issue.

 

System.debug('Id: '+id);

 

siteBOM = [Select Unit_Price__c, Site_Qty__c, Site_Extended_Amount__c, Part__c, Description__c From Project_Product__c
                      where Project_Name__c= :id  and Site_Qty__c > 0
                      Order by Part__c desc];
 

return siteBom;

 

I'm sure the issue will be with the id param, but let me know either way :)

 

Wes

jayhunterjayhunter

Solved!  And the answer was even dumber than I thought.  Thanks to you I verified that the proper ID was being passed into the method, but no child records were being retured by the query.  That's because my query was only selecting records with Site_Qty__c > 0, and the dummy record I passed in didn't have that field set.  Duh!  So creating the dummy record w/ Site_Qty__c = 1 resulted in the expected result, and all asserts pass now.

 

Many many thanks for your help on this, I really appreaciate it.