Category: Salesforce

noimage

Month of Testing: Advanced Topics in Salesforce Unit Testing (Part 3 of 3)

This is the third part of a three-part blog series about testing. We will be talking about:

Why We Test Apex Testing in Depth Advanced Topics in Salesforce Unit Testing

These advanced patterns and ideas help increase your test’s effectiveness. They focus on improving data generation, speeding up test execution and improving isolation. They’re definitely not required for effective tests, but they do help.

Advanced data generation

In our last post, we created test data in a @testSetup annotated method. This works fine, but can make test maintenance tedious. Consider the work required to add a validation rule, or require a field on the account object. A test factory can generate the account object, but we’ll likely have to edit code and redeploy it. To make things easier, we can create data and store it in a static resource. Then during our test’s @testSetup method, we load that data from the static resource. This technique enhances the definitiveness of our tests. It helps by isolating data issues from code issues. Let’s take a look at how this works in three easy steps. Most importantly, it makes maintaining your tests easier. How? By using static resources, any admin you work with can add new data at any time. Add a new permission set? Just add the appropriate data in the CSV and your tests will test the new permission set when run.

Let’s say you need to load account data for your tests. Rather than creating known edge-case data to accompany generic test data from your TestFactory, create a CSV file like this:

Name,Website,Phone,BillingStreet,BillingCity,BillingState,BillingPostalCode,BillingCountry
sForceTest1,
http://www.sforcetest1.com,(415) 901-7000,The Landmark @ One Market,San Francisco,CA,94105,US
sForceTest2,http://www.sforcetest2.com,(415) 901-7000,The Landmark @ One Market Suite 300,San Francisco,CA,94105,US
sForceTest3,http://www.sforcetest3.com,(415) 901-7000,1 Market St,San Francisco,CA,94105,US

Note: Your CSV file must have field names as the first row! Once you’ve created this CSV file, you can save it in a static resource.

I tend to name my static resources after the test class that uses it, with the name of the object appended. i.e.: MyClass_tests.Account.csv

Once you’ve got a static resource with your CSV data, it’s simple to load that data in your test class.

@isTest private class MyClass_Tests { @testSetup static void loadTestDataFromStaticResource(){ //Lets load the account csv! List<sObject> accts = Test.loadData(Account.sObjectType, ‘MyClass_tests.accounts.csv’); System.assertEquals(accts.size(), 3, ‘Unable to create some accounts from CSV file’); insert accts; } }

This style of creating test data has some unique advantages. For instance, your product management and QA teams can now contribute test data. If a bug arises, your QA team can add a row to the CSV, upload it and your tests will run with that data! You’ll still have to deploy the new static resource version. Static resources, however, are easier and faster to deploy.

Of course, this may seem a bit limited, since tests most often need many objects, all related to one another. Thankfully, there’s a simple trick to solve this issue as well. Let’s say we need to insert accounts and contacts related to those accounts. Your CSV’s might

Summer’18: Rethink Trigger Logic with Apex Switch

With 17,110 points on the IdeaExchange idea, the arrival of the switch statement in Apex in the Summer’18 release is an exciting addition to the language that should please many developers.

About switch

As a language construct, switch comes in a number of forms in many languages. You might have seen a similar logical construct referred to as case, select, or some other things. The mouthful of a technical definition of switch is a multiway branch logical control flow feature. If you don’t want to spend time parsing that, it’s basically a syntax structure to evaluate a variable against many possible values without having a bunch of repetitive else if blocks. It can reduce repetitive code and improve clarity and readability of logical code paths.

Switch in Apex

Each implementation of this feature in each language needs to work for that language. Apex is no different — key point here being Apex is not a general purpose programming language. It is a Salesforce domain-specific language solving problems for developers working with the Lightning Platform.

One minor obstacle is that Apex greatly resembles Java, which uses the syntax switch…case. Because of this resemblance, many developers expect Apex to follow Java syntax and conventions. Only trouble is in Apex the word “case” already represents the class for the Case sObject. Even if the compiler could be made to cope with a keyword of “case” alongside a class called Case, it isn’t going to help the cause of readability or clear clean code. So although Apex resembles Java in many ways, the when keyword is preferred (Largely based on feedback from early beta testers in the Trailblazer community group). Here is a basic representation of the syntax with a String variable being compared to String literals:

switch on someStringVar { when ‘value 1’ { //…do something… } when ‘value 2’, ‘value 3’ { //…do some other thing } when ‘value 4’ { //…do this thing… } when else { //…under all other circumstances } }

Those of you who have used a version of switch statement in the C-family of languages will immediately notice the absence of a break statement in each when block.

If you really did take notice, good job!

That’s because in Apex there is no fall-through. This means the first logical branch is executed, then no others. In other words, the first executed branch blocks any following branches in the switch block.

The last Apex-specific feature I’ll mention is the types that you are allowed to switch on. Unremarkably, String, Integer and Long can all be compared to a literal value. But there are also sObject identifier and enum comparisons. These bring some new prospects to how a developer might now structure their code, especially in triggers.

Switch on sObject type

Allowing to evaluate when based on sObject type is exciting. Let’s consider a result set from a custom object, where we have queried the Owner field. Owner is polymorphic in a custom object, meaning it

Summer ’18: Updated Tracking for IoT Orchestrations

Get insight into your orchestration data

A challenge for working with IoT Explorer has been a lack of insight into the actual data driving the orchestrations. You set up your variables, define some rules, turn on your IoT devices and swing over to the traffic tab to watch the states shift and … nothing happens.

(Note: Gru is not the property of Salesforce)

What would you do? Previously you would have to bounce out of IoT Explorer and find some other means to match up the actual data versus the expected results. Some developers have created logs via triggers or Process Builder. Personally, I’ve had to go to the device layer to see what is being sent over the wire.

In Summer’18, you are able to just go to the the tracker configuration icon in the upper right:

 

Enter in a value for a related context or orchestration. In this example, I’m using a known device ID:

 

Once started you will get a detailed list of events coming into the orchestration and if it matched your rules or not:

 

If you think your device should be triggering a state change and it is not matching the rule, you can drill right down to the specific JSON data in question:

 

Having to hop out of IoT Explorer to having a direct view into the incoming data and how the rules respond should result in a dramatic reduction of time spent debugging. Since you can define the specific key value, you are only getting the data you want to monitor and not the potentially overwhelming deep well of IoT data devices can generate. You can also filter down to optionally see things like errors.

Get started quickly with the IoT Explorer Quick Start

While some people may literally have IoT hardware randomly strewn across our homes (Maybe shoved into soda bottles and LEGOs), many haven’t taken that plunge yet. If you want to see a sample of connecting a smart device to Salesforce IoT, head over to Trailhead and give the IoT Explorer Quick Start a try. This Quick Start uses an HTML5 application running on Heroku to mimic the behavior of a smart thermostat. You can easily control the “actual” and desired temperatures to see them reflected within Salesforce IoT. To see the new trackers in action, sign up for a Summer’18 org if you don’t already have access to one. The key value you see in this article, “CUCGRITU3RVWKUL8,” is the value we use for the smart thermostat’s device ID.

About the author

Josh Birk is a Developer Evangelist at Salesforce and has a history of wrangling strings, cats, digital assistants and robots. He’ll be at Connections in June, Sydney Down Under Dreamin’ in July, and Dreamforce in September.