<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jesse Altman</title>
	<atom:link href="https://jessealtman.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://jessealtman.com</link>
	<description>Software Architect</description>
	<lastBuildDate>Fri, 17 May 2024 17:13:20 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6</generator>

<image>
	<url>https://jessealtman.com/wp-content/uploads/2024/04/cropped-jesse-candid-32x32.jpg</url>
	<title>Jesse Altman</title>
	<link>https://jessealtman.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>TrailheaDX Global Gathering 2017!</title>
		<link>https://jessealtman.com/2017/07/30/trailheadx-global-gathering-2017/</link>
		
		<dc:creator><![CDATA[Jesse Altman]]></dc:creator>
		<pubDate>Sun, 30 Jul 2017 16:03:01 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://jessealtman.com/?p=2349</guid>

					<description><![CDATA[On Thursday July 27th, my local user group, the Lehigh Valley Salesforce Developer Group, participated in the TrailheaDX Global Gathering #tdx17. TrailheaDX is Salesforce&#8217;s main developer conference for the year. While the main event occurred at the end of June, over the last few weeks, over 200 user groups from around the world have been<div class="more-link">
				 <a href="https://jessealtman.com/2017/07/30/trailheadx-global-gathering-2017/" class="link-btn theme-btn"><span>Read More </span> <i class="fa fa-caret-right"></i></a>
			</div>]]></description>
										<content:encoded><![CDATA[
<p>On Thursday July 27th, my local user group, the <a href="https://www.meetup.com/Lehigh-Valley-Salesforce-Developer-Group/events/241084612/" target="_blank" rel="noopener">Lehigh Valley Salesforce Developer Group</a>, participated in the TrailheaDX Global Gathering <a href="https://twitter.com/search?q=%23TDX17" target="_blank" rel="noopener">#tdx17</a>. <a href="https://developer.salesforce.com/trailheadx" target="_blank" rel="noopener">TrailheaDX</a> is Salesforce&#8217;s main developer conference for the year. While the main event occurred at the end of June, over the last few weeks, over 200 user groups from around the world have been holding their own events as part of the TrailheaDX Global Gathering.</p>



<p>Our event kicked off as we do each month, with some pizza, drinks, and great conversation. It was amazing to see the turnout for the global event. We had several new attendees and we hope they were intrigued enough to come back!</p>


<div class="wp-block-image">
<figure class="alignleft"><a href="http://jessealtman.com/wp-content/uploads/2017/07/IMG_20170727_184804.jpg"><img decoding="async" src="http://jessealtman.com/wp-content/uploads/2017/07/IMG_20170727_184804-1024x768.jpg" alt="" class="wp-image-2357"/></a></figure></div>


<p>After some great conversations, <a href="http://peterknolle.com/" target="_blank" rel="noopener">Peter Knolle</a> (<a href="https://twitter.com/PeterKnolle" target="_blank" rel="noopener">@PeterKnolle</a>) started the official meeting. He went over some key information, including watching a fantastic TrailheaDX &#8217;17 hype video! After that, everyone was excited to learn more.</p>


<div class="wp-block-image">
<figure class="alignleft"><a href="http://jessealtman.com/wp-content/uploads/2017/07/IMG_20170727_185549.jpg"><img decoding="async" src="http://jessealtman.com/wp-content/uploads/2017/07/IMG_20170727_185549-1024x768.jpg" alt="" class="wp-image-2359"/></a></figure></div>


<p>The main focus of the meeting was around <a href="https://developer.salesforce.com/platform/dx" target="_blank" rel="noopener">Salesforce DX</a>. <a href="http://www.wadewegner.com/" target="_blank" rel="noopener">Wade Wegner</a> (<a href="https://twitter.com/WadeWegner" target="_blank" rel="noopener">@WadeWegner</a>) did an enlightening session at TrailheaDX 2017 for an introduction to Salesforce DX. We watched that session together to learn more.</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="Introduction to Salesforce DX" width="640" height="360" src="https://www.youtube.com/embed/Pf33nrsqZOc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>After watching the presentation, we discussed Salesforce DX and how it could be utilized. We also had some general conversation around how we use Salesforce and how to convince IT departments to invest on the platform. All in all, it was a fun evening. We closed the meeting up with a group photo before heading out for a few beers, some appetizers, and more discussion.</p>



<figure class="wp-block-image"><a href="http://jessealtman.com/wp-content/uploads/2017/07/20368803_1591469490877541_2373092764330772407_o.jpg"><img decoding="async" src="http://jessealtman.com/wp-content/uploads/2017/07/20368803_1591469490877541_2373092764330772407_o.jpg" alt=""/></a></figure>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Simple Trick to Immediately Improve for New Developers</title>
		<link>https://jessealtman.com/2017/03/26/simple-trick-to-immediately-improve-for-new-developers/</link>
		
		<dc:creator><![CDATA[Jesse Altman]]></dc:creator>
		<pubDate>Sun, 26 Mar 2017 19:29:53 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://jessealtman.com/?p=2279</guid>

					<description><![CDATA[I&#8217;ve written before about writing clean code and being a software professional, both of which are large contributors to becoming a better developer. However, today I want to talk about 1 small thing new developers can do to immediately improve their capabilities in the eyes of their peers. That one thing is consistency! This might<div class="more-link">
				 <a href="https://jessealtman.com/2017/03/26/simple-trick-to-immediately-improve-for-new-developers/" class="link-btn theme-btn"><span>Read More </span> <i class="fa fa-caret-right"></i></a>
			</div>]]></description>
										<content:encoded><![CDATA[
<p>I&#8217;ve written before about writing <a href="http://jessealtman.com/2014/08/clean-code-on-the-force-com-platform/" target="_blank" rel="noopener">clean code</a> and being a <a href="http://jessealtman.com/2014/07/software-professionalism-on-the-force-com-platform/" target="_blank" rel="noopener">software professional</a>, both of which are large contributors to becoming a better developer. However, today I want to talk about 1 small thing new developers can do to immediately improve their capabilities in the eyes of their peers. That one thing is consistency!</p>



<p>This might seem like such a silly thing, but before you click away, hear me out. The most important part of software development tends to happen after the initial piece of functionality is written. The reality is a large part of an application&#8217;s cost is spent during maintenance. Part of this reality is that you will have to come back to the work you are doing now and relearn the code that you had written. This means it is incredibly important to make your code consistent, which has the benefit of making it easier to read and easier to modify. Let me give you an example.</p>



<p>Imagine the company you work for sells flowers. You create a very simple page which allows you to create a flower order and add flowers to it. On your first attempt, this is how the controller code turns out:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="public with sharing class FlowerOrderController 
{
    private Flower_Order__c flowerOrder;
    public List&lt;Flower&gt; availableFlowers{
        get;
        set;
    }
    
	public FlowerOrderController(ApexPages.StandardController stdController)
    {
flowerOrder = (Flower_Order__c)stdController.getRecord();
    }
    
    private void setAvailableFlowers(){
        	availableFlowers = new List&lt;Flower&gt;();
        List&lt;Flower__c&gt; flowersFromDb = [SELECT Id, Name FROM  Flower__c WHERE Is_Active__c = true];
        for(Flower__c singleFlower:flowersFromDb){
        availableFlowers.add(new Flower(singleFlower));
        }
    }
    
    public PageReference saveFlowerOrder(){
        Savepoint sp = Database.setSavepoint();
        try
        {
        insert flowerOrder;
        List&lt;Flower_Order_Item__c&gt; selectedFlowers = new List&lt;Flower_Order_Item__c&gt;();
        for(Flower flowerWrapper:availableFlowers){
        if(flowerWrapper.isSelected){
        selectedFlowers.add(new Flower_Order_Item__c(
        Flower__c = flowerWrapper.singleFlower.Id, 
Flower_Order__c = flowerOrder.Id
        ));}}
        
        insert selectedFlowers;
return new ApexPages.StandardController(flowerOrder).view();
        }
        catch(Exception ex)
{
        Database.rollback(sp);ApexPages.addMessages(ex);
        }
return null;
    }
    
    public class Flower
    {
        public Flower__c   singleFlower {get;
set;}
public Boolean isSelected {get;set;}
        
        public Flower(Flower__c singleFlower)
        {
        this.singleFlower = singleFlower;
        }}


}" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> with sharing </span><span style="color: #81A1C1">class</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">FlowerOrderController</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">private</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">Flower_Order__c</span><span style="color: #D8DEE9FF"> flowerOrder</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">List</span><span style="color: #ECEFF4">&lt;</span><span style="color: #81A1C1">Flower</span><span style="color: #ECEFF4">&gt;</span><span style="color: #D8DEE9FF"> availableFlowers</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">get;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">set;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span></span>
<span class="line"><span style="color: #D8DEE9FF">	</span><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">FlowerOrderController</span><span style="color: #ECEFF4">(</span><span style="color: #8FBCBB">ApexPages</span><span style="color: #ECEFF4">.</span><span style="color: #8FBCBB">StandardController</span><span style="color: #D8DEE9FF"> stdController</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9">flowerOrder</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">Flower_Order__c</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9">stdController</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">getRecord</span><span style="color: #ECEFF4">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">private</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">setAvailableFlowers</span><span style="color: #ECEFF4">(){</span></span>
<span class="line"><span style="color: #D8DEE9FF">        	</span><span style="color: #D8DEE9">availableFlowers</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">List</span><span style="color: #ECEFF4">&lt;</span><span style="color: #81A1C1">Flower</span><span style="color: #ECEFF4">&gt;()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">List</span><span style="color: #ECEFF4">&lt;</span><span style="color: #81A1C1">Flower__c</span><span style="color: #ECEFF4">&gt;</span><span style="color: #D8DEE9FF"> flowersFromDb </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">[</span><span style="color: #81A1C1">SELECT</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">Id</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">Name</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">FROM</span><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">Flower__c</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">WHERE</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">Is_Active__c</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">true</span><span style="color: #ECEFF4">]</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">for</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">Flower__c</span><span style="color: #D8DEE9FF"> singleFlower</span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9">flowersFromDb</span><span style="color: #ECEFF4">){</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">availableFlowers</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">add</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">Flower</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">singleFlower</span><span style="color: #ECEFF4">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">PageReference</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">saveFlowerOrder</span><span style="color: #ECEFF4">(){</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">Savepoint</span><span style="color: #D8DEE9FF"> sp </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">Database</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">setSavepoint</span><span style="color: #ECEFF4">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">try</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">insert</span><span style="color: #D8DEE9FF"> flowerOrder</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">List</span><span style="color: #ECEFF4">&lt;</span><span style="color: #81A1C1">Flower_Order_Item__c</span><span style="color: #ECEFF4">&gt;</span><span style="color: #D8DEE9FF"> selectedFlowers </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">List</span><span style="color: #ECEFF4">&lt;</span><span style="color: #81A1C1">Flower_Order_Item__c</span><span style="color: #ECEFF4">&gt;()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">for</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">Flower</span><span style="color: #D8DEE9FF"> flowerWrapper</span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9">availableFlowers</span><span style="color: #ECEFF4">){</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">if</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">flowerWrapper</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">isSelected</span><span style="color: #ECEFF4">){</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">selectedFlowers</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">add</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">Flower_Order_Item__c</span><span style="color: #ECEFF4">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">Flower__c</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">flowerWrapper</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">singleFlower</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">Id</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #D8DEE9">Flower_Order__c</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">flowerOrder</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">Id</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">))</span><span style="color: #81A1C1">;</span><span style="color: #ECEFF4">}}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">insert</span><span style="color: #D8DEE9FF"> selectedFlowers</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">ApexPages</span><span style="color: #ECEFF4">.</span><span style="color: #8FBCBB">StandardController</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">flowerOrder</span><span style="color: #ECEFF4">).</span><span style="color: #88C0D0">view</span><span style="color: #ECEFF4">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">catch</span><span style="color: #ECEFF4">(</span><span style="color: #8FBCBB">Exception</span><span style="color: #D8DEE9FF"> ex</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">Database</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">rollback</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">sp</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span><span style="color: #8FBCBB">ApexPages</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">addMessages</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">ex</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">null;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">class</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">Flower</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">Flower__c</span><span style="color: #D8DEE9FF">   singleFlower </span><span style="color: #ECEFF4">{</span><span style="color: #81A1C1">get;</span></span>
<span class="line"><span style="color: #81A1C1">set;</span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">Boolean</span><span style="color: #D8DEE9FF"> isSelected </span><span style="color: #ECEFF4">{</span><span style="color: #81A1C1">get;set;</span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">Flower</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">Flower__c</span><span style="color: #D8DEE9FF"> singleFlower</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">this</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">singleFlower</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">singleFlower</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}}</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">}</span></span></code></pre></div>



<p>How many times have you seen something like this? This code will run just fine and it should do exactly what we expect. The problem is that it is difficult to read. This will make it very hard to modify in the future, as you have to relearn what the code does when you go to make a change. The most frustrating part of all of this? There is simply no reason for it. It is very easy to clean something like this up, and it provides a ton of value. New developers focus so much on just getting something to work, that once they do, they sometimes just stop to make sure it continues to work. They got the job done, right? Well, why not spend 5 minutes, clean up the file, and you can get something like this:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="public with sharing class FlowerOrderController {
    private Flower_Order__c flowerOrder;
    public List&lt;Flower&gt; availableFlowers {get;set;}
    
    public FlowerOrderController(ApexPages.StandardController stdController){
        flowerOrder = (Flower_Order__c)stdController.getRecord();
    }
    
    private void setAvailableFlowers(){
        availableFlowers = new List&lt;Flower&gt;();
        List&lt;Flower__c&gt; flowersFromDb = [
            SELECT
            	Id, Name
            FROM
            	Flower__c
            WHERE
            	Is_Active__c = true
        ];
        for(Flower__c singleFlower:flowersFromDb){
            availableFlowers.add(new Flower(singleFlower));
        }
    }
    
    public PageReference saveFlowerOrder(){
        Savepoint sp = Database.setSavepoint();
        try{
            insert flowerOrder;
            List&lt;Flower_Order_Item__c&gt; selectedFlowers = new List&lt;Flower_Order_Item__c&gt;();
            for(Flower flowerWrapper:availableFlowers){
                if(flowerWrapper.isSelected){
                    selectedFlowers.add(
                        new Flower_Order_Item__c(
                            Flower__c = flowerWrapper.singleFlower.Id, 
                            Flower_Order__c = flowerOrder.Id
                        )
                    );
                }
            }
            insert selectedFlowers;
            
            return new ApexPages.StandardController(flowerOrder).view();
        }catch(Exception ex){
            Database.rollback(sp);
            ApexPages.addMessages(ex);
        }
        
        return null;
    }
    
    public class Flower{
        public Flower__c singleFlower {get;set;}
        public Boolean isSelected {get;set;}
        
        public Flower(Flower__c singleFlower){
        	this.singleFlower = singleFlower;
        }
    }
}" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> with sharing </span><span style="color: #81A1C1">class</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">FlowerOrderController</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">private</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">Flower_Order__c</span><span style="color: #D8DEE9FF"> flowerOrder</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">List</span><span style="color: #ECEFF4">&lt;</span><span style="color: #81A1C1">Flower</span><span style="color: #ECEFF4">&gt;</span><span style="color: #D8DEE9FF"> availableFlowers </span><span style="color: #ECEFF4">{</span><span style="color: #81A1C1">get;set;</span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">FlowerOrderController</span><span style="color: #ECEFF4">(</span><span style="color: #8FBCBB">ApexPages</span><span style="color: #ECEFF4">.</span><span style="color: #8FBCBB">StandardController</span><span style="color: #D8DEE9FF"> stdController</span><span style="color: #ECEFF4">){</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">flowerOrder</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">Flower_Order__c</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9">stdController</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">getRecord</span><span style="color: #ECEFF4">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">private</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">setAvailableFlowers</span><span style="color: #ECEFF4">(){</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">availableFlowers</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">List</span><span style="color: #ECEFF4">&lt;</span><span style="color: #81A1C1">Flower</span><span style="color: #ECEFF4">&gt;()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">List</span><span style="color: #ECEFF4">&lt;</span><span style="color: #81A1C1">Flower__c</span><span style="color: #ECEFF4">&gt;</span><span style="color: #D8DEE9FF"> flowersFromDb </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">[</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">SELECT</span></span>
<span class="line"><span style="color: #D8DEE9FF">            	</span><span style="color: #81A1C1">Id</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">Name</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">FROM</span></span>
<span class="line"><span style="color: #D8DEE9FF">            	</span><span style="color: #81A1C1">Flower__c</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">WHERE</span></span>
<span class="line"><span style="color: #D8DEE9FF">            	</span><span style="color: #81A1C1">Is_Active__c</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">true</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">]</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">for</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">Flower__c</span><span style="color: #D8DEE9FF"> singleFlower</span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9">flowersFromDb</span><span style="color: #ECEFF4">){</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #D8DEE9">availableFlowers</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">add</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">Flower</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">singleFlower</span><span style="color: #ECEFF4">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">PageReference</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">saveFlowerOrder</span><span style="color: #ECEFF4">(){</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">Savepoint</span><span style="color: #D8DEE9FF"> sp </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">Database</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">setSavepoint</span><span style="color: #ECEFF4">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">try</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">insert</span><span style="color: #D8DEE9FF"> flowerOrder</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">List</span><span style="color: #ECEFF4">&lt;</span><span style="color: #81A1C1">Flower_Order_Item__c</span><span style="color: #ECEFF4">&gt;</span><span style="color: #D8DEE9FF"> selectedFlowers </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">List</span><span style="color: #ECEFF4">&lt;</span><span style="color: #81A1C1">Flower_Order_Item__c</span><span style="color: #ECEFF4">&gt;()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">for</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">Flower</span><span style="color: #D8DEE9FF"> flowerWrapper</span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9">availableFlowers</span><span style="color: #ECEFF4">){</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #81A1C1">if</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">flowerWrapper</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">isSelected</span><span style="color: #ECEFF4">){</span></span>
<span class="line"><span style="color: #D8DEE9FF">                    </span><span style="color: #D8DEE9">selectedFlowers</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">add</span><span style="color: #ECEFF4">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">                        </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">Flower_Order_Item__c</span><span style="color: #ECEFF4">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">                            </span><span style="color: #D8DEE9">Flower__c</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">flowerWrapper</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">singleFlower</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">Id</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #D8DEE9FF">                            </span><span style="color: #D8DEE9">Flower_Order__c</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">flowerOrder</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">Id</span></span>
<span class="line"><span style="color: #D8DEE9FF">                        </span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">                    </span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">insert</span><span style="color: #D8DEE9FF"> selectedFlowers</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">ApexPages</span><span style="color: #ECEFF4">.</span><span style="color: #8FBCBB">StandardController</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">flowerOrder</span><span style="color: #ECEFF4">).</span><span style="color: #88C0D0">view</span><span style="color: #ECEFF4">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">catch</span><span style="color: #ECEFF4">(</span><span style="color: #8FBCBB">Exception</span><span style="color: #D8DEE9FF"> ex</span><span style="color: #ECEFF4">){</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #8FBCBB">Database</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">rollback</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">sp</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #8FBCBB">ApexPages</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">addMessages</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">ex</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">null;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">class</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">Flower</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">Flower__c</span><span style="color: #D8DEE9FF"> singleFlower </span><span style="color: #ECEFF4">{</span><span style="color: #81A1C1">get;set;</span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">Boolean</span><span style="color: #D8DEE9FF"> isSelected </span><span style="color: #ECEFF4">{</span><span style="color: #81A1C1">get;set;</span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">public</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">Flower</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">Flower__c</span><span style="color: #D8DEE9FF"> singleFlower</span><span style="color: #ECEFF4">){</span></span>
<span class="line"><span style="color: #D8DEE9FF">        	</span><span style="color: #81A1C1">this</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">singleFlower</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">singleFlower</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span></code></pre></div>



<p>I didn&#8217;t change a single thing between those two examples, except for consistently formatting my code. That simple change, which only took about a minute or two, immediately improves the quality of the work I have done and makes it much easier to maintain in the future. Moral of the story is that it is important to make sure things are clean before you finish your work. Spending a few minutes to simply format your code, can help tremendously in the future. Once you get into the habit of constantly keeping it formatted, it will become second nature and you will immediately be viewed in a better light by your fellow devs. Enjoy!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ApexMocks with Stub API</title>
		<link>https://jessealtman.com/2017/02/11/apexmocks-with-stub-api/</link>
		
		<dc:creator><![CDATA[Jesse Altman]]></dc:creator>
		<pubDate>Sat, 11 Feb 2017 20:50:58 +0000</pubDate>
				<guid isPermaLink="false">http://jessealtman.com/?p=2266</guid>

					<description><![CDATA[At Dreamforce &#8217;16, I gave a presentation with David Frudd and John Leen on the Stub API and how it works with ApexMocks. Apex provides a stub API for implementing a mocking framework. A mocking framework has many benefits. It can streamline and improve testing and help you create faster, more reliable tests. You can<div class="more-link">
				 <a href="https://jessealtman.com/2017/02/11/apexmocks-with-stub-api/" class="link-btn theme-btn"><span>Read More </span> <i class="fa fa-caret-right"></i></a>
			</div>]]></description>
										<content:encoded><![CDATA[<p>At Dreamforce &#8217;16, I gave a presentation with <a href="https://twitter.com/frup42" target="_blank">David Frudd</a> and John Leen on the <a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_stub_api.htm" target="_blank">Stub API</a> and how it works with <a href="https://github.com/financialforcedev/fflib-apex-mocks" target="_blank">ApexMocks</a>.</p>
<blockquote><p>Apex provides a stub API for implementing a mocking framework. A mocking framework has many benefits. It can streamline and improve testing and help you create faster, more reliable tests. You can use it to test classes in isolation, which is important for unit testing. Building your mocking framework with the stub API can also be beneficial because stub objects are generated at runtime. Because these objects are generated dynamically, you don’t have to package and deploy test classes. You can build your own mocking framework, or you can use one built by someone else.</p></blockquote>
<p>I was honored to be able to speak at my first Dreamforce and my two co-presenters were fantastic to work with. If you aren&#8217;t familiar with this topic, please check out either the <a href="https://www.salesforce.com/video/297000/" target="_blank">Dreamforce &#8217;16 video</a> or watch the same presentation I gave a the <a href="https://www.meetup.com/Lehigh-Valley-Salesforce-Developer-Group/events/235132897/" target="_blank">Lehigh Valley Salesforce Developer Group</a></p>
<p><iframe title="Fast Simple Unit Tests with ApexMocks using the Stub API" width="640" height="360" src="https://www.youtube.com/embed/tOeCZ3vRyAI?start=8&#038;feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Beyond Trailhead &#8211; Apex Testing</title>
		<link>https://jessealtman.com/2015/06/23/beyond-trailhead-apex-testing/</link>
		
		<dc:creator><![CDATA[Jesse Altman]]></dc:creator>
		<pubDate>Tue, 23 Jun 2015 10:45:55 +0000</pubDate>
				<guid isPermaLink="false">http://jessealtman.com/?p=2176</guid>

					<description><![CDATA[Trailhead is an interactive learning path through the basic building blocks of the Salesforce1 Platform. Test your knowledge of the platform while earning points and badges to celebrate your achievements. All of this is broken down into different modules, making it easy for every developer to learn Salesforce in a few hour chunks. This series<div class="more-link">
				 <a href="https://jessealtman.com/2015/06/23/beyond-trailhead-apex-testing/" class="link-btn theme-btn"><span>Read More </span> <i class="fa fa-caret-right"></i></a>
			</div>]]></description>
										<content:encoded><![CDATA[<p><a href="https://developer.salesforce.com/trailhead" target="_blank">Trailhead</a> is an interactive learning path through the basic building blocks of the Salesforce1 Platform. Test your knowledge of the platform while earning points and badges to celebrate your achievements. All of this is broken down into different modules, making it easy for every developer to learn Salesforce in a few hour chunks. This series will follow a different module each post, giving a comprehensive analysis of the module. The focus of this post will be on expanding what is taught in the module into greater depth and taking your experience beyond Trailhead and into more actual Salesforce work.</p>
<h2><a href="https://developer.salesforce.com/trailhead/force_com_dev_beginner/apex_testing/apex_testing_intro" target="_blank">Getting Started with Apex Unit Tests</a></h2>
<p>This is a fantastic start to explaining unit tests. I think the fifteen minute estimate is valid, although the test scenario using <a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_date.htm" target="_blank"><code>Date</code></a> classes can be tricky for someone first learning unit tests. That may push it out past fifteen minutes. I&#8217;d suggest reading up on the Date class more and experimenting with it. While that wasn&#8217;t the focus on this specific piece, it can be trickier than other primitive data types, so it is good to get some practice.</p>
<p>Outside of that, there were a few oddities that I noticed. One, the challenge asks for you to create <code>TestVerifyDate</code> yet the example always ended their classes with Test rather than prepending it. Either way is fine, but it is important to be consistent when writing your test classes. Find a good paradigm that works for you and stick with it. I&#8217;d also suggest consistently using <a href="http://en.wikipedia.org/wiki/CamelCase" target="_blank">camelCase</a>. Some of the code here did not always use it. You can choose your own formatting, but Apex typically uses camelCase so it wouldn&#8217;t be a bad idea to keep that in mind. Consistency is key to great development.</p>
<h2><a href="https://developer.salesforce.com/trailhead/force_com_dev_beginner/apex_testing/apex_testing_triggers" target="_blank">Testing Apex Triggers</a></h2>
<p><a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers.htm" target="_blank">Triggers</a> are an interesting aspect of Salesforce that can cause headaches if done improperly. This example is pretty straight forward, but I would highly consider following Salesforce&#8217;s own posted <a href="https://developer.salesforce.com/page/Trigger_Frameworks_and_Apex_Trigger_Best_Practices" target="_blank">Trigger Best Practices</a>. Specifically, the use of logic-less triggers, one trigger per object, etc. By using a framework like this, it will be much easier to breakdown where your logic exists in real world situations as well as properly test the implementations outside of a specific trigger.</p>
<h2><a href="https://developer.salesforce.com/trailhead/force_com_dev_beginner/apex_testing/apex_testing_data" target="_blank">Creating Test Data for Apex Tests</a></h2>
<p>It was a fantastic idea to call out the usage of a Test Utilities class for creating your data. That is a common mistake I see most new developers make (by not having one). I also thought the mention of branch coverage was a good idea. I felt this module was really good (despite some of the naming issues I mentioned above). I&#8217;d consider taking this to the next level by utilizing the new <a href="http://docs.releasenotes.salesforce.com/en-us/spring15/release-notes/rn_apex_test_setup_methods.htm" target="_blank"><code>@testSetup</code></a> annotation to encapsulate your data creation in a single location. I&#8217;d also consider more <a href="http://jessealtman.com/2013/09/proper-unit-test-structure-in-apex/" target="_blank">complex Test Utilities classes</a>.</p>
<hr/>
<p>Overall, I&#8217;d say this is a fantastic module. Some minor chances to expand, but for the most part they include some great concepts for developers new to unit testing.</p>
<blockquote><p>I highly recommend Trailhead for everyone. Even if I called out some different things that could be expanded on, it doesn&#8217;t change my opinion that Trailhead is a fantastic tool for learning the development practices on the Force.com platform.</p></blockquote>
<p>For more information related to Trailhead, please read the <a href="https://developer.salesforce.com/page/Trailhead_FAQ" target="_blank">Trailhead FAQ</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Salesforce Lightning Week Rocked!</title>
		<link>https://jessealtman.com/2015/03/16/salesforce-lightning-week-rocked/</link>
		
		<dc:creator><![CDATA[Jesse Altman]]></dc:creator>
		<pubDate>Mon, 16 Mar 2015 10:45:42 +0000</pubDate>
				<guid isPermaLink="false">http://jessealtman.com/?p=2150</guid>

					<description><![CDATA[There was a fantastic turn out to Salesforce Lightning Week world wide! So many people learning Lightning at once was fantastic. Watching the #golightningfast and #lightningdevweek hashtag this week has been a joy. It was even better contributing! Once again, a Salesforce global user group meetup significantly helped attendance at this month&#8217;s Lehigh Valley Salesforce<div class="more-link">
				 <a href="https://jessealtman.com/2015/03/16/salesforce-lightning-week-rocked/" class="link-btn theme-btn"><span>Read More </span> <i class="fa fa-caret-right"></i></a>
			</div>]]></description>
										<content:encoded><![CDATA[<p>There was a fantastic turn out to <a href="http://jessealtman.com/2015/03/salesforce-lightning-week-begins/" target="_blank">Salesforce Lightning Week</a> world wide! So many people learning Lightning at once was fantastic. Watching the <a href="https://twitter.com/search?q=%23goLightningFast&#038;src=tyah" target="_blank">#golightningfast</a> and <a href="https://twitter.com/search?q=%23lightningdevweek&#038;src=tyah" target="_blank">#lightningdevweek</a> hashtag this week has been a joy. It was even better contributing!</p>
<p>Once again, a Salesforce global user group meetup significantly helped attendance at this month&#8217;s <a href="http://www.meetup.com/Lehigh-Valley-Salesforce-Developer-Group/events/220513854/" target="_blank">Lehigh Valley Salesforce Developer User Group</a> (<a href="https://twitter.com/LVSFDCDUG" target="_blank">@LVSFDCDUG</a>/<a href="https://www.youtube.com/user/LVSFDCDUG" target="_blank">Youtube</a>) meeting. We had one of our best turn outs in months from all of Salesforce&#8217;s marketing, but also from some promotion from the <a href="http://www.meetup.com/Girl-Develop-It-Lehigh-Valley/events/220666361/" target="_blank">local Girl Develop It chapter</a>, a great group looking for more members! <a href="http://peterknolle.com/" target="_blank">Peter Knolle</a> (<a href="https://twitter.com/PeterKnolle" target="_blank">@peterknolle</a>) kicked off the event with the best <a href="http://www.salesforce.com/platform/services/lightning/" target="_blank">Lightning</a> presentation I have seen so far, explaining and demonstrating Lightning Connect, Lightning Process Builder, Lightning App Builder, and Lightning Components. We were incredibly fortunate to have Peter, a Force.com MVP and 6x certified Salesforce architect, presenting. He is one of the world experts on Lightning, sharing his expertise through several fantastic <a href="http://peterknolle.com/posts/" target="_blank">blog posts on his own site</a> as well as on the <a href="https://developer.salesforce.com/blogs/blog/author/pknolle" target="_blank">Salesforce Developer Blogs</a> (with more to come over the next few weeks).</p>
<p>After food, drinks, and Peter&#8217;s presentation, we jumped directly into hands on workshops, one of my personal favorite things to do with a user group. It is always interesting when you start working with fellow Salesforce enthusiasts and start hearing their use cases for the different products, specifically Lightning this meetup. Several of our members had begun writing Lightning Components, using the Lightning Process Builder, and experimenting with Lightning Connect. On top of that, it is fun to work as a group towards learning and discovering new technology.</p>
<p>After all of this Lightning talk, we finished the evening up with some drinks and more food at a local bar. The Lightning conversation was very active, and at the end of it, that really is the goal of these developer weeks. Let&#8217;s get more people involved and let&#8217;s keep them involved. So, what&#8217;s the next step for you?</p>
<p>If you don&#8217;t have one, get a <a href="https://developer.salesforce.com/signup_lightningweek?d=70130000000NFJ3" target="_blank">Lightning Dev Org</a>. This is step 1, and should be followed even if you have a dev org already. These orgs come ready for Lightning development. The next step would be deciding what you want to learn first. You have:</p>
<ul>
<li><a href="http://developerforce.github.io/lightning-connect-tutorial/index.html" target="_blank">Lightning Connect Tutorial</a></li>
<li><a href="http://developerforce.github.io/lightning-process-builder-tutorial/" target="_blank">Lightning Process Builder Tutorial</a></li>
<li><a href="http://developerforce.github.io/lightning-components-tutorial/" target="_blank">Lightning Components Tutorial</a></li>
<li><a href="https://developer.salesforce.com/trailhead/module/lightning_components" target="_blank"/>Lightning on Trailhead</a></li>
</ul>
<p>After you have gone through the material, start to share your work! Share your experience on Twitter, Facebook, LinkedIn, etc! Write some blog posts (if you do not have a blog, I can work with you to guest blog here or on other blogs &#8211; <a href="http://jessealtman.com/contact/" target="_blank">just contact me</a>)! Finally, make sure to continue to attend your user group. I know there is a large influx of attendees during this week, but you can get value year round from your local user group. Not only are you interacting with a larger set of people in your industry (perfect for recruiting/sales/job search), but in general you will find a ton of really smart people who will be able to teach you knew things.</p>
<p>It is a fun, exciting time to be involved with Salesforce. How was your Salesforce Lightning Week? What meetup did you attend? What are you most excited about with Lightning? Share in the comments below!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Salesforce Lightning Week Begins!</title>
		<link>https://jessealtman.com/2015/03/09/salesforce-lightning-week-begins/</link>
		
		<dc:creator><![CDATA[Jesse Altman]]></dc:creator>
		<pubDate>Mon, 09 Mar 2015 14:27:43 +0000</pubDate>
				<guid isPermaLink="false">http://jessealtman.com/?p=2142</guid>

					<description><![CDATA[Salesforce Lightning Week has begun! Salesforce1 Lightning provides a plethora of new functionality to the Salesforce platform, but in it&#8217;s simplest form you can think about it as the new generation of the Salesforce1 platform. What&#8217;s Happening? 100+ Salesforce Developer, User, and Non-Profit groups across the globe will be meeting during Lightning Week to experience<div class="more-link">
				 <a href="https://jessealtman.com/2015/03/09/salesforce-lightning-week-begins/" class="link-btn theme-btn"><span>Read More </span> <i class="fa fa-caret-right"></i></a>
			</div>]]></description>
										<content:encoded><![CDATA[<p><a href="https://developer.salesforce.com/developer-week" target="_blank">Salesforce Lightning Week</a> has begun! <a href="http://jessealtman.com/2014/11/what-is-salesforce1-lightning/" target="_blank">Salesforce1 Lightning provides a plethora of new functionality to the Salesforce platform</a>, but in it&#8217;s simplest form you can think about it as the new generation of the Salesforce1 platform.</p>
<p><iframe title="Salesforce App Cloud with Lightning Overview Demo" width="640" height="360" src="https://www.youtube.com/embed/2JEP_CUiEAk?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></p>
<h2>What&#8217;s Happening?</h2>
<blockquote><p>100+ Salesforce Developer, User, and Non-Profit groups across the globe will be meeting during Lightning Week to experience first hand the power of Salesforce1 Lightning. Join a group near you for demos, training, and to meet Salesforce experts. No matter your experience level you&#8217;ll learn new tools that you can start using right away.</p></blockquote>
<h2>Should I Attend?</h2>
<p><strong>Yes!</strong> It is just that simple. Everyone should attend. There are so many meetings being held around the world, hopefully there is one close enough to you to make it possible. If you are a developer, learning about Lightning is important because it is going to change the way you work with Salesforce. If you are an admin, learning about Lightning is important because it is going to change the way you work with Salesforce. If you are a consultant, learning about Lightning is important because it is going to change the way you work with Salesforce. See where I am going with this? Lightning is a huge set of functionality and topics and it doesn&#8217;t pertain to any specific &#8220;role&#8221;. Lightning is bringing developers, admins, and consultants closer than ever before.</p>
<h2>RSVP Now!</h2>
<p>There is still time! Choose from one of the many <a href="https://developer.salesforce.com/developer-week" target="_blank">DUGs participating around the world</a>, RSVP to the event, and join the rest of us! You will enjoy it! Share your experience with the world using the <a href="https://twitter.com/hashtag/lightningdevweek?src=hash" target="_blank">#lightningdevweek hashtag</a>! If you live in the Lehigh Valley, PA area, please consider attending the <a href="http://www.meetup.com/Lehigh-Valley-Salesforce-Developer-Group/events/220513854/" target="_blank">LVSFDCDUG Meetup on March 12th at 6pm</a> with me! Have fun!</p>
<p><iframe loading="lazy" src="https://www.google.com/maps/d/embed?mid=zIs2P4R9hI8Q.kxp59dKpOFy8" width="615" height="461"></iframe></p>
<h2>Get a Head Start</h2>
<p>Once you have RSVPed to an event, get a head start learning about Lightning using <a href="https://developer.salesforce.com/trailhead" target="_blank">Trailhead</a>. There is a fantastic <a href="https://developer.salesforce.com/trailhead/module/lightning_components" target="_blank">Lightning hands-on tutorial</a> now available on Trailhead. When you are done, try some other modules on areas you may not be 100% familiar with. Also, feel free to check out some of the great <a href="https://developer.salesforce.com/trailhead" target="_blank">Lightning content being pushed to the Salesforce Developer blogs</a> on a regular basis.</p>
<p>Have a fantastic Salesforce Lightning Week and be sure to share your experience online with others!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>LVSFDCDUG: ApexMocks Talk</title>
		<link>https://jessealtman.com/2015/02/23/lvsfdcdug-apexmocks-talk/</link>
		
		<dc:creator><![CDATA[Jesse Altman]]></dc:creator>
		<pubDate>Mon, 23 Feb 2015 11:45:46 +0000</pubDate>
				<guid isPermaLink="false">http://jessealtman.com/?p=2136</guid>

					<description><![CDATA[I recently gave a talk at Lehigh Valley Salesforce Developer Group (@LVSFDCDUG). For the past few meetups, we have been live streaming and recording each of the presentations on Youtube. There are several other awesome presentations on there, but please feel free to check out my recent talk on ApexMocks and my other articles on<div class="more-link">
				 <a href="https://jessealtman.com/2015/02/23/lvsfdcdug-apexmocks-talk/" class="link-btn theme-btn"><span>Read More </span> <i class="fa fa-caret-right"></i></a>
			</div>]]></description>
										<content:encoded><![CDATA[<p>I recently gave a talk at <a href="http://www.meetup.com/Lehigh-Valley-Salesforce-Developer-Group/" target="_blank">Lehigh Valley Salesforce Developer Group</a> (<a href="https://twitter.com/LVSFDCDUG" target="_blank">@LVSFDCDUG</a>). For the past few meetups, we have been live streaming and recording each of the presentations on <a href="https://www.youtube.com/user/LVSFDCDUG" target="_blank">Youtube</a>. There are several other awesome presentations on there, but please feel free to check out my recent talk on ApexMocks and <a href="http://jessealtman.com/tag/apexmocks/" target="_blank">my other articles on the topic</a>. Enjoy!</p>
<p><iframe loading="lazy" title="Enhancing Unit Tests with ApexMocks" width="640" height="360" src="https://www.youtube.com/embed/HBulci-5xIs?start=85&#038;feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></p>
<blockquote><p>
<strong>Note:</strong> Apologies for recording the &#8220;presenter&#8221; view, that will be fixed for the next recording!
</p></blockquote>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>New Spring &#8217;15 Features: Mapping</title>
		<link>https://jessealtman.com/2015/02/09/new-spring-15-features-mapping/</link>
		
		<dc:creator><![CDATA[Jesse Altman]]></dc:creator>
		<pubDate>Mon, 09 Feb 2015 11:45:22 +0000</pubDate>
				<guid isPermaLink="false">http://jessealtman.com/?p=2120</guid>

					<description><![CDATA[The Spring &#8217;15 release is upon us! As with every Salesforce release, it comes with a plethora of new features. One of the cooler aspects of the Spring &#8217;15 release is the addition of some mapping functionality. Standard Address Fields Show Google Maps Records with standard address fields now display a Google Maps image of<div class="more-link">
				 <a href="https://jessealtman.com/2015/02/09/new-spring-15-features-mapping/" class="link-btn theme-btn"><span>Read More </span> <i class="fa fa-caret-right"></i></a>
			</div>]]></description>
										<content:encoded><![CDATA[<p>The Spring &#8217;15 release is <a href="https://trust.salesforce.com/trust/maintenance/" target="_blank">upon us</a>! As with every Salesforce release, it comes with <a href="http://docs.releasenotes.salesforce.com/en-us/spring15/release-notes/salesforce_release_notes.htm" target="_blank">a plethora of new features</a>. One of the cooler aspects of the Spring &#8217;15 release is the addition of some mapping functionality.</p>
<h2>Standard Address Fields Show Google Maps</h2>
<blockquote><p>Records with standard address fields now display a Google Maps image of the address. This saves users time by letting them see where their contacts or accounts are located, instead of having to locate addresses in a separate browser tab.</p>
<p>On a record, go to the detail page to see the Google Maps image on the address field. To generate a map image, an address must include the street and city fields and either the state, postal code, or the country. If an address field is missing any of the required information, a map won’t display.</p></blockquote>
<p>Address fields will now look like:</p>
<p><img decoding="async" src="http://jessealtman.com/wp-content/uploads/2015/02/maps_google_rn.png"/></p>
<p>This feature also <a href="http://docs.releasenotes.salesforce.com/en-us/spring15/release-notes/rn_mobile_salesforce1_newfeat_maps.htm" target="_blank">works in Salesforce1</a>.</p>
<p><img decoding="async" src="http://jessealtman.com/wp-content/uploads/2015/02/s1_maps.png"/></p>
<p>This functionality will be on by default. To disable it, go to <strong>Customize | Maps and Locations | Settings</strong> and uncheck <code>Enable Maps and Location Services</code>.</p>
<h2>Limitations Changed for Geolocation Fields (Generally Available)</h2>
<blockquote><p>
<a href="https://help.salesforce.com/HTViewHelpDoc?id=custom_field_geolocate_overview.htm&#038;language=en_US" target="_blank">Geolocation fields</a>, formerly available only as a beta release, are now generally available. Now you can get the most out of geolocation thanks to fewer limitations and increased functionality, including improvements in Visual Workflow, workflow updates and approvals, Apex, search tools, and more.</p>
<p>Spring ’15 includes the following changes to geolocation field limitations.</p>
<ul>
<li>Geolocation fields are available in Visual Workflow and in formula-based criteria in workflow rules and approval processes, but cannot be used in filter-based criteria in workflow rules and approval processes.</li>
<li>Geolocation fields can be searched in SOQL and SOSL.</li>
<li><code>DISTANCE</code> formulas are supported in:
<ul>
<li>Entry criteria for workflow rules and approval processes</li>
<li>Field update actions in workflow rules and approval processes</li>
<li>Custom validation rules</li>
</ul>
</li>
<li>The only formula functions that you can use with <a href="https://www.salesforce.com/developer/docs/api/Content/compound_fields_geolocation.htm" target="_blank">compound fields</a> are <code>ISBLANK</code>, <code>ISCHANGED</code>, and <code>ISNULL</code>. You can’t use <code>BLANKVALUE</code>, <code>CASE</code>, <code>NULLVALUE</code>, <code>PRIORVALUE</code>, or the equality and comparison operators with compound fields. The equality and comparison operators include = and == (equal), <> and != (not equal), < (less than), > (greater than), <= (less than or equal), >= (greater than or equal), &#038;&#038; (AND), and || (OR).</li>
<li>Geolocation fields are now queryable in Apex. However, their locations are editable in Apex only as components of the compound field. Read and set geolocation field components by appending “__latitude__s” or “__longitude__s” to the field name, instead of the usual “__c.” For example:<br />
[java]<br />
Double theLatitude = myObject__c.aLocation__latitude__s;<br />
myObject__c.aLocation__longitude__s = theLongitude;<br />
[/java]
</li>
</ul>
</blockquote>
<h2>Use Visualforce Map Components to Show Location Data More Clearly</h2>
<p>There are two new fantastic Visualforce tags, <a href="http://www.salesforce.com/us/developer/docs/pages/Content/pages_compref_map.htm" target="_clear"><code>apex:map</code></a> and <a href="http://www.salesforce.com/us/developer/docs/pages/Content/pages_compref_mapMarker.htm" target="_clear"><code>apex:mapMarker</code></a>, that are <a href="http://docs.releasenotes.salesforce.com/en-us/spring15/release-notes/rn_vf_mapping_components.htm" target="_blank">included as part of Spring &#8217;15</a>.</p>
<blockquote><p>
Visualforce mapping components make it simple to create maps that use third-party mapping services. Visualforce maps are interactive, JavaScript-based maps complete with zooming, scrolling, and markers based on your Salesforce or other data. Create stand-alone map pages, maps that you can insert into page layouts, and even mobile maps for Salesforce1.</p>
<p>Create Visualforce maps with a set of related mapping components. <apex:map> defines a map canvas, including map size, type, center point, and initial zoom level. <apex:mapMarker> child components define markers to place on the map, by address or geolocation (latitude and longitude).</p>
<p>Maps that you define generate JavaScript code to render onto the page. This JavaScript connects to a mapping service and builds the map by fetching map tiles, placing markers, and even geocoding addresses if you don’t have a latitude and longitude. After the map renders, your users can interact with the map by panning and zooming, just like they’re used to with other popular map sites. The effect is if you wrote your own custom JavaScript to interact with a third-party mapping service, but without needing to actually write that JavaScript. You define the map in Visualforce and get the mapping JavaScript for free.
</p></blockquote>
<p>An example of both tags in action:</p>
<div style="overflow-x:scroll;">
<div style="width:1150px;">
[html]<br />
<apex:page standardController="Account"><br />
	<!-- This page must be accessed with an Account Id in the URL. For example: https://<salesforceInstance>/apex/NearbyContacts?id=001D000000JRBet --><br />
	<apex:pageBlock><br />
		<apex:pageBlockSection title="Contacts For {!Account.Name}"><br />
			<apex:dataList value="{!Account.Contacts}" var="contact"><br />
				<apex:outputText value="{!contact.Name}"/><br />
			</apex:dataList><br />
			<apex:map width="600px" height="400px" mapType="roadmap" center="{!Account.BillingStreet},{!Account.BillingCity},{!Account.BillingState}"><br />
				<apex:repeat value="{!Account.Contacts}" var="contact"><br />
					<apex:mapMarker title="{!contact.Name}" position="{!contact.MailingStreet},{!contact.MailingCity},{!contact.MailingState}"/><br />
				</apex:repeat><br />
			</apex:map><br />
		</apex:pageBlockSection><br />
	</apex:pageBlock><br />
</apex:page><br />
[/html]
</div>
</div>
<p>Result:</p>
<p><img decoding="async" src="http://jessealtman.com/wp-content/uploads/2015/02/pages_maps_markers.png" width="615px"/></p>
<h2>My Observations</h2>
<p>Salesforce has done a fantastic job with this release of visualizing location data and making it more end user friendly. As the world becomes more and more mobile, this type of information will be very useful to have at your fingertips.</p>
<p>Enjoy and feel free to test it out on your own <a href="https://www.salesforce.com/form/signup/prerelease-spring15.jsp" target="_blank">Spring &#8217;15 Pre-Release Org</a>!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Spring &#8217;15 Feature: Apex Flex Queue</title>
		<link>https://jessealtman.com/2015/02/02/spring-15-feature-apex-flex-queue/</link>
					<comments>https://jessealtman.com/2015/02/02/spring-15-feature-apex-flex-queue/#comments</comments>
		
		<dc:creator><![CDATA[Jesse Altman]]></dc:creator>
		<pubDate>Mon, 02 Feb 2015 11:45:14 +0000</pubDate>
				<guid isPermaLink="false">http://jessealtman.com/?p=2109</guid>

					<description><![CDATA[The Spring &#8217;15 release is approaching quickly! As with every Salesforce release, it comes with a plethora of new features. Over the next few weeks, I am going to outline what I find to be some of the cooler features. Apex Flex Queue One of the nicest features of Spring &#8217;15 in my mind is<div class="more-link">
				 <a href="https://jessealtman.com/2015/02/02/spring-15-feature-apex-flex-queue/" class="link-btn theme-btn"><span>Read More </span> <i class="fa fa-caret-right"></i></a>
			</div>]]></description>
										<content:encoded><![CDATA[<p>The Spring &#8217;15 release is <a href="https://trust.salesforce.com/trust/maintenance/" target="_blank">approaching quickly</a>! As with every Salesforce release, it comes with <a href="http://docs.releasenotes.salesforce.com/en-us/spring15/release-notes/salesforce_release_notes.htm" target="_blank">a plethora of new features</a>. Over the next few weeks, I am going to outline what I find to be some of the cooler features.</p>
<h2>Apex Flex Queue</h2>
<p>One of the nicest features of Spring &#8217;15 in my mind is <a href="http://docs.releasenotes.salesforce.com/en-us/spring15/release-notes/rn_apex_flex_queue_ga.htm" target="_blank">Apex Flex Queue</a>. From the release notes:</p>
<blockquote><p>Submit up to 100 batch jobs simultaneously and actively manage the order of the queued jobs to control which batch jobs are processed first. This enhancement provides you more flexibility in managing your batch jobs.</p>
<p>Previously, you could submit only up to five batch jobs simultaneously. The Apex flex queue enables you to submit up to 100 additional batch jobs for execution. Any jobs that are submitted for execution are in holding status and are placed in the Apex flex queue. Up to 100 batch jobs can be in the holding status. When system resources become available, the system picks up jobs from the top of the Apex flex queue and moves them to the batch job queue. The system can process up to five queued or active jobs simultaneously. The status of these moved jobs changes from Holding to Queued. Queued jobs get executed when the system is ready to process new jobs.</p>
<p>Administrators can modify the order of jobs that are held in the Apex flex queue to control when they get processed by the system. For example, administrators can move a batch job up to the first position in the holding queue so that it’s the first job that gets processed when the system fetches the next held job from the flex queue. Without administrator intervention, jobs are processed first-in first-out—in the order in which they’re submitted. To monitor and reorder held batch jobs in the Salesforce user interface, from Setup click Jobs | Apex Flex Queue.</p></blockquote>
<h2>My Observations</h2>
<p>This is awesome! Being able to queue up 100 jobs rather than 5 is a huge difference (that is a 2000% increase)! The important thing to note about this change is the addition of the <code>Holding</code> status. From the release notes:</p>
<blockquote><p>
The <a href="http://www.salesforce.com/us/developer/docs/object_reference/index_CSH.htm#sforce_api_objects_asyncapexjob.htm" target="_blank"><code>AsyncApexJob</code></a> object, which represents a batch job, has a new Status field value of <code>Holding</code>. This new status indicates that the job is placed in the flex queue and is waiting to be processed when system resources become available.
</p></blockquote>
<p>This aspect of the change is crucial. It doesn&#8217;t matter what version of Apex your code runs against, it needs to be able to support this new status. Specifically, this affects all queries against the <code>AsyncApexJob</code>. Take for instance (prior to Spring &#8217;15):</p>
<div style="overflow-x:scroll;">
<div style="width:700px;">
[sql]<br />
List<AsyncApexJob> existingJobs = [<br />
	SELECT Id, Status, CreatedBy.Name, CreatedDate<br />
	FROM AsyncApexJob<br />
	WHERE (Status = &#8216;Queued&#8217; or Status = &#8216;Processing&#8217; or Status = &#8216;Preparing&#8217;)<br />
	AND ApexClass.Name = &#8216;TestBatchClass&#8217;<br />
];<br />
[/sql]
</div>
</div>
<p>This query would have found all existing batch jobs for the <code>TestBatchClass</code> prior to Spring &#8217;15. However, due to the addition of the new <code>Holding</code> status, this no longer finds all of the existing jobs. This query needs to be modified slightly to:</p>
<div style="overflow-x:scroll;">
<div style="width:800px;">
[sql]<br />
List<AsyncApexJob> existingJobs = [<br />
	SELECT Id, Status, CreatedBy.Name, CreatedDate<br />
	FROM AsyncApexJob<br />
	WHERE (Status = &#8216;Queued&#8217; or Status = &#8216;Processing&#8217; or Status = &#8216;Preparing&#8217; or Status = &#8216;Holding&#8217;)<br />
	AND ApexClass.Name = &#8216;TestBatchClass&#8217;<br />
];<br />
[/sql]
</div>
</div>
<p>As mentioned before, different than most changes to Apex, this is a data change. It requires code running on previous versions to take into account the proper Status values.</p>
<p>Enjoy and feel free to test it out on your own <a href="https://www.salesforce.com/form/signup/prerelease-spring15.jsp" target="_blank">Spring &#8217;15 Pre-Release Org</a>!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessealtman.com/2015/02/02/spring-15-feature-apex-flex-queue/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>New Spring &#8217;15 Feature: @testSetup</title>
		<link>https://jessealtman.com/2015/01/26/new-spring-15-feature-testsetup/</link>
					<comments>https://jessealtman.com/2015/01/26/new-spring-15-feature-testsetup/#comments</comments>
		
		<dc:creator><![CDATA[Jesse Altman]]></dc:creator>
		<pubDate>Mon, 26 Jan 2015 11:45:50 +0000</pubDate>
				<guid isPermaLink="false">http://jessealtman.com/?p=2073</guid>

					<description><![CDATA[The Spring &#8217;15 release is approaching quickly! As with every Salesforce release, it comes with a plethora of new features. Over the next few weeks, I am going to outline what I find to be some of the cooler features. @testSetup One of the nicest features of Spring &#8217;15 in my mind is @testSetup. From<div class="more-link">
				 <a href="https://jessealtman.com/2015/01/26/new-spring-15-feature-testsetup/" class="link-btn theme-btn"><span>Read More </span> <i class="fa fa-caret-right"></i></a>
			</div>]]></description>
										<content:encoded><![CDATA[<p>The Spring &#8217;15 release is <a href="https://trust.salesforce.com/trust/maintenance/" target="_blank">approaching quickly</a>! As with every Salesforce release, it comes with <a href="http://docs.releasenotes.salesforce.com/en-us/spring15/release-notes/salesforce_release_notes.htm" target="_blank">a plethora of new features</a>. Over the next few weeks, I am going to outline what I find to be some of the cooler features.</p>
<h2>@testSetup</h2>
<p>One of the nicest features of Spring &#8217;15 in my mind is <a href="http://docs.releasenotes.salesforce.com/en-us/spring15/release-notes/rn_apex_test_setup_methods.htm" target="_blank"><code>@testSetup</code></a>. From the release notes:</p>
<blockquote><p>Use test setup methods (methods that are annotated with <code>@testSetup</code>) to create test records once and then access them in every test method in the test class. Test setup methods can be time-saving when you need to create reference or prerequisite data for all test methods, or a common set of records that all test methods operate on.</p>
<p>Test setup methods can reduce test execution times especially when you’re working with many records. Test setup methods enable you to create common test data easily and efficiently. By setting up records once for the class, you don’t need to re-create records for each test method. Also, because the rollback of records that are created during test setup happens at the end of the execution of the entire class, the number of records that are rolled back is reduced. As a result, system resources are used more efficiently compared to creating those records and having them rolled back for each test method.</p>
<p>If a test class contains a test setup method, the testing framework executes the test setup method first, before any test method in the class. Records that are created in a test setup method are available to all test methods in the test class and are rolled back at the end of test class execution. If a test method changes those records, such as record field updates or record deletions, those changes are rolled back after each test method finishes execution. The next executing test method gets access to the original unmodified state of those records.</p></blockquote>
<h2>In Action</h2>
<p>Let&#8217;s consider the following class:</p>
<div style="overflow-x:scroll;">
<div style="width:700px;">
[java]<br />
public class AccountService {<br />
    public static List<Account> getAllAccounts(){<br />
        return [SELECT Id, Name FROM Account LIMIT 500];<br />
    }</p>
<p>    public static List<Opportunity> getOpportunitiesOnAccount(Id accountId){<br />
        return [SELECT Id, Name FROM Opportunity WHERE AccountId = :accountId];<br />
    }</p>
<p>    public static void updateAccountName(Account account, String accountName){<br />
        account.Name = accountName;<br />
        update account;<br />
    }<br />
}<br />
[/java]
</p></div>
</div>
<p>Typically, this would require a unit test class that looks like:</p>
<div style="overflow-x:scroll;">
<div style="width:800px;">
[java]<br />
@isTest<br />
public class AccountServiceTest {<br />
    static testMethod void testGetAllAccounts(){<br />
        List<Account> accounts = new List<Account>();<br />
        for(Integer i=0;i < 10;i++){
            accounts.add(new Account(Name = 'Test Acc'));
        }
        insert accounts;
        
        Test.startTest();
        List<Account> accountsFromService = AccountService.getAllAccounts();<br />
        Test.stopTest();</p>
<p>        System.assertEquals(10, accountsFromService.size(), &#8216;There should be 10 accounts&#8217;);<br />
    }</p>
<p>    static testMethod void testGetOpportunitiesOnAccount(){<br />
        Account acc = new Account();<br />
        acc.Name = &#8216;Test Account&#8217;;<br />
        insert acc;<br />
        List<Opportunity> opportunities = new List<Opportunity>();<br />
        for(Integer i=0;i < 10;i++){
            opportunities.add(new Opportunity(
                Name = 'Test Opp', 
                AccountId = acc.Id,
                StageName = 'Closed Won',
                CloseDate = Date.today()
            ));
        }
        insert opportunities;
        
        Test.startTest();
        List<Opportunity> opportunitiesFromService = AccountService.getOpportunitiesOnAccount(acc.Id);<br />
        Test.stopTest();</p>
<p>        System.assertEquals(10, opportunitiesFromService.size(), &#8216;There are 10 opportunities&#8217;);<br />
    }</p>
<p>    static testMethod void updateAccountName(){<br />
        Account acc = new Account();<br />
        acc.Name = &#8216;Test Account&#8217;;<br />
        insert acc;</p>
<p>        Test.startTest();<br />
        AccountService.updateAccountName(acc, &#8216;Updated Account&#8217;);<br />
        Test.stopTest();</p>
<p>        Account accFromDb = [SELECT Id, Name FROM Account WHERE Id = :acc.Id];<br />
        System.assertEquals(&#8216;Updated Account&#8217;, accFromDb.Name, &#8216;The account name has been updated&#8217;);<br />
    }<br />
}<br />
[/java]
</p></div>
</div>
<p>So, what&#8217;s wrong with the current approach above? Well, you need to generate the same data several times, but it is also done in slightly different pieces of code. This can cause maintainability problems as well as well as a slow process generating the same data. How would this look using the new <code>@testSetup</code> method?</p>
<div style="overflow-x:scroll;">
<div style="width:800px;">
[java]<br />
@isTest<br />
public class AccountServiceTest {<br />
    @testSetup static void setupTestData(){<br />
        List<Account> accounts = new List<Account>();<br />
        for(Integer i=0;i < 10;i++){
            accounts.add(new Account(Name = 'Test Acc'));
        }
        insert accounts;
        List<Opportunity> opportunities = new List<Opportunity>();<br />
        for(Account acc:accounts){<br />
            for(Integer i=0;i < 10;i++){
                opportunities.add(new Opportunity(
                    Name = 'Test Opp', 
                    AccountId = acc.Id,
                    StageName = 'Closed Won',
                    CloseDate = Date.today()
                ));
            }
        }
        insert opportunities;
    }
    
    static testMethod void testGetAllAccounts(){
        Test.startTest();
        List<Account> accountsFromService = AccountService.getAllAccounts();<br />
        Test.stopTest();</p>
<p>        System.assertEquals(10, accountsFromService.size(), &#8216;There should be 10 accounts&#8217;);<br />
    }</p>
<p>    static testMethod void testGetOpportunitiesOnAccount(){<br />
        Account acc = [SELECT Id, Name FROM Account WHERE Name = &#8216;Test Acc&#8217; LIMIT 1];</p>
<p>        Test.startTest();<br />
        List<Opportunity> opportunitiesFromService = AccountService.getOpportunitiesOnAccount(acc.Id);<br />
        Test.stopTest();</p>
<p>        System.assertEquals(10, opportunitiesFromService.size(), &#8216;There are 10 opportunities&#8217;);<br />
    }</p>
<p>    static testMethod void updateAccountName(){<br />
        Account acc = [SELECT Id, Name FROM Account WHERE Name = &#8216;Test Acc&#8217; LIMIT 1];</p>
<p>        Test.startTest();<br />
        AccountService.updateAccountName(acc, &#8216;Updated Account&#8217;);<br />
        Test.stopTest();</p>
<p>        Account accFromDb = [SELECT Id, Name FROM Account WHERE Id = :acc.Id];<br />
        System.assertEquals(&#8216;Updated Account&#8217;, accFromDb.Name, &#8216;The account name has been updated&#8217;);<br />
    }<br />
}<br />
[/java]
</p></div>
</div>
<p>Note how there is only a single method that inserts data and also note that I can directly query records immediately in a test yet <a href="https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_seealldata_using.htm" target="_blank"><code>@SeeAllData</code></a> is not set. We are accessing the data that was set up when the class was first instantiated. Now let&#8217;s tweak the code just slightly to verify the rollback works properly.</p>
<div style="overflow-x:scroll;">
<div style="width:950px;">
[java]<br />
@isTest<br />
public class AccountServiceTest {<br />
    @testSetup static void setupTestData(){<br />
        List<Account> accounts = new List<Account>();<br />
        for(Integer i=0;i < 10;i++){
            accounts.add(new Account(Name = 'Test Acc'));
        }
        insert accounts;
        List<Opportunity> opportunities = new List<Opportunity>();<br />
        for(Account acc:accounts){<br />
            for(Integer i=0;i < 10;i++){
                opportunities.add(new Opportunity(
                    Name = 'Test Opp', 
                    AccountId = acc.Id,
                    StageName = 'Closed Won',
                    CloseDate = Date.today()
                ));
            }
        }
        insert opportunities;
    }
    
    static testMethod void testGetAllAccounts(){
        Test.startTest();
        List<Account> accountsFromService = AccountService.getAllAccounts();<br />
        Test.stopTest();</p>
<p>        System.assertEquals(10, accountsFromService.size(), &#8216;There should be 10 accounts&#8217;);<br />
    }</p>
<p>    static testMethod void testGetOpportunitiesOnAccount(){<br />
        Account acc = [SELECT Id, Name FROM Account WHERE Name = &#8216;Test Acc&#8217; LIMIT 1];</p>
<p>        Test.startTest();<br />
        List<Opportunity> opportunitiesFromService = AccountService.getOpportunitiesOnAccount(acc.Id);<br />
        Test.stopTest();</p>
<p>        System.assertEquals(10, opportunitiesFromService.size(), &#8216;There are 10 opportunities&#8217;);<br />
    }</p>
<p>    static testMethod void updateAccountName(){<br />
        Account acc = [SELECT Id, Name FROM Account WHERE Name = &#8216;Test Acc&#8217; LIMIT 1];</p>
<p>        Test.startTest();<br />
        AccountService.updateAccountName(acc, &#8216;Updated Account&#8217;);<br />
        Test.stopTest();</p>
<p>        Account accFromDb = [SELECT Id, Name FROM Account WHERE Id = :acc.Id];<br />
        System.assertEquals(&#8216;Updated Account&#8217;, accFromDb.Name, &#8216;The account name has been updated&#8217;);<br />
    }</p>
<p>    static testMethod void testRollbackOnTestData(){<br />
        List<Account> accounts = [SELECT Id, Name FROM Account WHERE Name = &#8216;Updated Account&#8217;];</p>
<p>        System.assertEquals(0, accounts.size(), &#8216;There are no accounts with that name because they have been rolled back&#8217;);<br />
    }<br />
}<br />
[/java]
</p></div>
</div>
<p>The last test was added to verify that the data rolls back to it&#8217;s original state, which it does (otherwise we would find an account with the updated name).</p>
<h2>Other Considerations</h2>
<p>From the release notes:</p>
<blockquote>
<ul>
<li>Test setup methods are supported only with the default data isolation mode for a test class. If the test class or a test method has access to organization data by using the <code>@isTest(SeeAllData=true)</code> annotation, test setup methods aren’t supported in this class. Because data isolation for tests is available for API versions 24.0 and later, test setup methods are also available for those versions only.</li>
<li>Multiple test setup methods are allowed in a test class, but the order in which they’re executed by the testing framework isn’t guaranteed.</li>
<li>If a fatal error occurs during the execution of a test setup method, such as an exception that’s caused by a DML operation or an assertion failure, the entire test class fails, and no further tests in the class are executed.</li>
<li>If a test setup method calls a non-test method of another class, no code coverage is calculated for the non-test method.</li>
</ul>
</blockquote>
<h2>My Observations</h2>
<p>This is a big step forward to achieving faster test runs. Faster unit test execution time is pivotal to <a href="http://en.wikipedia.org/wiki/Test-driven_development" target="_blank">Test Driven Development (TDD)</a>. This is a feature that will immediately impact the way everyone develops as every single Salesforce developer will want to utilize this functionality.</p>
<p>The main downside to all of this is the fact that the only way to access this data is to query it back from the database. While this may not be a problem in the simple example above, it may become more of an issue as the complexity grows.</p>
<p>With that said, it is still worth it to use this new functionality. You will still want to incorporate good unit test practices (such as using a <code>TestUtils</code> class), this will just be a new aspect of <a href="http://jessealtman.com/2013/09/proper-unit-test-structure-in-apex/" target="_blank">proper unit test structure</a>. Enjoy and feel free to test it out on your own <a href="https://www.salesforce.com/form/signup/prerelease-spring15.jsp" target="_blank">Spring &#8217;15 Pre-Release Org</a>!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessealtman.com/2015/01/26/new-spring-15-feature-testsetup/feed/</wfw:commentRss>
			<slash:comments>26</slash:comments>
		
		
			</item>
	</channel>
</rss>
