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
SlanganSlangan 

Test Class Woes

Hello Everyone,

 

First I want to say thanks for such a great forum, I have learned so much here and really appreciate the amazing feedback I always get. It is truly awesome to see the level of expertise out there willing to help us newbies!!!

 

If I might impose one more time on the greater mind-share out there to help me with the following problem, I would be really appreciative. I am a bit stumped, and have been trying to figure this out on my own for over a week with no success.

 

I have just started learning test classes, and have figured out how to instantiate an object and test strings. My issue is that I now have to test a more complex class that is way over my head - it has changing variables, inserts, etc.) and I have no idea how to test for that stuff? The code is below along with my non-test class (it doesn't actually test anything yet as I can't figure out how to set a concrete variable for this!). Any help at all would be appreciated.

 

Thanks in advance for helping me learn.

 

 

public class addSOA { ApexPages.StandardController controller; public addSOA (ApexPages.StandardController c) { controller = c;} public PageReference emailSOA() { // Get the opportunity Id and name Opportunity opportunity = [SELECT id, name,Opportunity_No__c FROM opportunity WHERE Id = :System.currentPageReference().getParameters().get('id')]; // Create PDF // Reference the page, pass in a parameter to force PDF PageReference pdf = new PageReference('/apex/SOApdf' + '?id=' + opportunity.id); pdf.getParameters().put('p','p'); pdf.setRedirect(true); // Grab the PDF! Blob b = pdf.getContent(); // Create the attachment against the Opportunity */ Attachment a = new Attachment(parentId = opportunity.id, name=opportunity.name + '-'+ opportunity.Opportunity_No__c+'-'+'SOA.pdf', body = b); // Insert the attachment insert a; // Create an email Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage (); email.setSaveAsActivity(true); email.setToAddresses(addresses); email.setSenderDisplayName('New Order'); email.setSubject('New SO Approval Created for Opportunity # ' + opportunity.Opportunity_No__c); email.setPlainTextBody('A new SO Approval has been created for ' + opportunity.Name +' , '+ opportunity.Opportunity_No__c+'. The SO Approval is attached.'); email.setHtmlBody('A new SO Approval has been created for' + '&nbsp;'+'<b>'+ opportunity.Name +'&nbsp;'+'</b>'+ opportunity.Opportunity_No__c+'. The SO Approval is attached.'+ ' To view this Opportunity <a href=https://na1.salesforce.com/'+ opportunity.Id +'><b>click here</b></a>'); // Create an email attachment Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment(); // Set name of PDF efa.setFileName(opportunity.Opportunity_No__c+'SOA.pdf'); // Set body of PDF efa.setBody(b); // Attach the PDF to your email email.setFileAttachments(new Messaging.EmailFileAttachment[] {efa}); // Send email & return to Opportunity Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email}); // Send the user back to the opportunity detail page */ return controller.view(); } String[] addresses = new String[]{}; public List<SelectOption> getItems() { List<SelectOption> options = new List<SelectOption>(); options.add(new SelectOption('aabimanan@krausglobal.com','Amu Abimanan')); options.add(new SelectOption('bfoster@krausglobal.com','Brian Foster')); options.add(new SelectOption('cdamiani@krausglobal.com','Chris Damiani')); options.add(new SelectOption('dpatel@krausglobal.com','Dev Patel')); options.add(new SelectOption('galdea@krausglobal.com','Gabriel Aldea')); options.add(new SelectOption('jwebb@krausglobal.com','Jason Webb')); options.add(new SelectOption('jdelcampo@krausglobal.com','Julian del Campo')); options.add(new SelectOption('mmandilaras@krausglobal.com','Manny Mandilaras')); options.add(new SelectOption('nestey@krausglobal.com','Norm Estey')); options.add(new SelectOption('ptopolnitsky@krausglobal.com','Penny Topolnitsky')); options.add(new SelectOption('rreimer@krausglobal.com','Roger Reimer')); options.add(new SelectOption('rdevisser@krausglobal.com','Ross Devisser')); options.add(new SelectOption('sbailey@krausglobal.com','Scott Bailey')); options.add(new SelectOption('slangan@krausglobal.com','Shannon Langan')); return options; } public String[] getAddresses() { return addresses; } public void setAddresses(String[] addresses) { this.addresses = addresses; } //****************** //Test Method //****************** public static testMethod void TestAddSOA() { // Insert test Opportunity Opportunity testOppty = new opportunity ( Name = 'Test Opportunity', Amount = 5000, StageName = 'Closed Won', CloseDate = System.today()); insert testOppty; // Instantiate VisualForce Page PageReference pg = Page.SOApdf; Test.setCurrentPage(pg); ApexPages.currentPage().getParameters().put('id', testOppty.id); // Instantiate addSOA controller ApexPages.StandardController c = new ApexPages.standardController(testOppty); addSOA qe = new addSOA(c); } }

 

 

 

AlsoDougAlsoDoug

While you have a couple of methods the code is actually fairly linear (not a lot of branching logic).

 

All you really need to do in your test method at end is call qe.emailSOA()and qe.getItems().

 

This will give you coverage % you want for the class.

 

Admittedly it's not going to prove much from a testing stand point beyond that the code executes with out error.

 

 

 

SlanganSlangan
How would I go about calling qe.emailSOA? Do I need to call each item in the method? I am reading the documentation on this but still don't entierly understand it. Can you please give me an example to help get me started?
AlsoDougAlsoDoug

Oh yeah if you want some unsolicted advice (and who doesn't :) ):

 

1. Don't start a class name with lower case (I know sales force is not case senstivie) 

 

2. Classes are generally nouns since they repsent things, actions done on things (IE add )

 

3. Also probably best to keep your test classes seperate from your normal classes. Just a organization thing.

AlsoDougAlsoDoug

OK here is your test method

 

All I have done to it is add the last 4 lines (2 of them comments).

 

 

//****************** //Test Method //****************** public static testMethod void TestAddSOA() { // Insert test Opportunity Opportunity testOppty = new opportunity ( Name = 'Test Opportunity', Amount = 5000, StageName = 'Closed Won', CloseDate = System.today()); insert testOppty; // Instantiate VisualForce Page PageReference pg = Page.SOApdf; Test.setCurrentPage(pg); ApexPages.currentPage().getParameters().put('id', testOppty.id); // Instantiate addSOA controller ApexPages.StandardController c = new ApexPages.standardController(testOppty); addSOA qe = new addSOA(c); //call the emailSOA method, it returns a pageReference but we really don't care about that qe.emailSOA(); //call the getItems method qe.getItems(); }

 

Run the code you originally posted and look at the test coverage % (you can just run the one file).

 

Add the lines I added and run it again.

 

You should get a huge jump in coverage %.

 

With unit tests you are really doing 2 things:

 

1. Making sure you execute as many lines as code as possible (giving you the coverage %)

2. Verifying your code is performing as expected

 

We are really just trying to get coverage with the tests above.

 

 

 

 

 

SlanganSlangan

Wow. Thanks. I still don't think I entirely understand why that is working, though. I thought I had to use a System.assert to qualify something as tested? :womanwink:

 

So now I am up to 52% coverage. It appears the qe.getItems() method is not covering anything when I look at my results. Any ideas?

 

BTW thanks for the help here - and for enduring my questions.

 

:smileyhappy: 

AlsoDougAlsoDoug

No problem with the questions. We were all new at some point in time.

 

In my previous post when I talked about unit tests doing two things one was getting coverage (lines of code executed ) and the other was verifying that the code is doing what you expect it to do.

 

You get coverage up by calling the methods in your class (like calling qe.emailSOA() in the test class which executes that method and its code in the original class)

 

You use the System.assert related stuff to verify that the code is doing what you expect it to do. A basic example of this would be if you had a method that took two numbers and added them together, to test this would compare the result of using the method to add the numbers with adding the numbers with code in your test class (yeah its kind of silly at times).

 

As to why getItems() is showing no coverage no idea. Make sure you are reading the results correctly and that you added that line to your test class (no insult meant). 

 

 

 

SlanganSlangan

No insult taken at all. I am very green at this and it was a fair question (plus I am learning a ton from you!).

 

I do have the code entered in my test method - but when I run the test all of the related code to the getItems() method is highlighted in red. Could this be because I am calling a string from a set of options (a checklist)? Would the items have to be checked (or set to selected somehow - not sure how to do this) so they would show (otherwise you would just have a blank string, wouldn't you???)?

 

 

//****************** //Test Method //****************** public static testMethod void TestAddSOA() { // Insert test Opportunity Opportunity testOppty = new opportunity ( Name = 'Test Opportunity', Amount = 5000, StageName = 'Closed Won', CloseDate = System.today()); insert testOppty; // Instantiate VisualForce Page PageReference pg = Page.SOApdf; Test.setCurrentPage(pg); ApexPages.currentPage().getParameters().put('id', testOppty.id); // Instantiate addSOA controller ApexPages.StandardController c = new ApexPages.standardController(testOppty); addSOA qe = new addSOA(c); //call the emailSOA method qe.emailSOA(); //call the getItems method qe.getItems(); } }

 

 

AlsoDougAlsoDoug

Should be no need for you to do anything except call that method in your tests.

 

The fact that all the method does is add values to  list and then returns that list should have no impact one way or the other.

 

Where are you running the test from? Can you paste screen shoot the results?

 

SlanganSlangan
AlsoDougAlsoDoug

 

Hey man I all see is two images that look liks this:

 

SlanganSlangan
I think I have figured out how to test the list options - if I test to see that the number of options equals the number I expect, and then set one of the options to a test option, I can then also test for that. I know that is a bad explanation, so I have pasted the code below:

// Test the List Options getItems() method List<SelectOption> options = qe.getItems(); System.assertEquals(options.size(), 14); String[] addresses = new String[1]; addresses[0] = 'test@krausglobal.com'; qe.setAddresses(addresses); System.assertEquals(qe.addresses[0], 'test@krausglobal.com'); qe.getAddresses();

 

I am now up to 97% coverage! The one line of code still not covered is

 

return controller.view();

 

THANKS AGAIN FOR ALL OF YOUR EXCELLENT HELP!!!!

 

 

AlsoDougAlsoDoug

Good to hear that you more or less figured it out :)

 

I wouldn't kill myself over that extra 3%. 

 

 

SlanganSlangan

You crack me up.

 

Thanks again.:smileyvery-happy:

Rick-ProfaceRick-Proface

Hello,

 

I'm trying to do the same thing and would like to use your code to start me off as I am new. Do you mind? If not, how would I call your class from a buttom or link?

 

Thanks,

Rick

SlanganSlangan

Go ahead and use the code - I am happy if it helps you. That's what these forums are for (and why we love them so).

 

Let me know how it turns out! ;-)