Skip to content

Instantly share code, notes, and snippets.

@AlwaysThinkin
Last active July 13, 2021 19:03
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save AlwaysThinkin/d872b8367acca2fc7e8fbf7806c8f178 to your computer and use it in GitHub Desktop.
Save AlwaysThinkin/d872b8367acca2fc7e8fbf7806c8f178 to your computer and use it in GitHub Desktop.
/* This Apex Class is a Unit Test Class and all the code can be checked by running the test.
* Copy this into a new Apex Class named "ControlFlow" and save it.
* As you read through it, look for "FIX ME!" and make the changes suggested.
* If your changes are correct all the tests (System Asserts) will pass.
*
* You can also see what's happening in the Logs by opening a Log and checking the Debug Only box
* you can compare the line numbers in the Log to the line number in the Class to find a specific
* debug entry.
*/
@isTest
public class ControlFlow {
static testMethod void logic(){
//IF statements. These are just like Workflow Rules.
if(true){
//And here is your Workflow Action in between the curly brackets
System.debug('Do Something!');
}
//you can condense it to one line if there's only one action.
if(true) System.debug('Still do something');
//prep a true/false variable for the next step.
Boolean myBool = true;
//use "else" when you only want the action to happen when your if case is false
//This is what Workflow Rules can't do: actions for multiple results from one rule
if(myBool){
System.debug('The Boolean was true');//only runs if myBool is true
} else {
System.debug('The Boolean was false');//only runs if myBool is false
}
System.debug('The Boolean doesn\'t matter here');//This line will always run
//you can string multiple condition cases with "else if"
if(myBool){
System.debug('The Boolean was: ' + myBool);
} else if(!myBool){
System.debug('The Boolean was: ' + myBool);
} else {
System.debug('Whoa! there was no value');
}
//FIX ME!: Try changing myBool to false and confirm that the conditions cascade to the next condition
//FIX ME!: Try not setting myBool to any value and see what happens...
//And just so you know it exists, there is the ternary operator for if-else statements
//This has to be used with variable assignment, so its use is limited but elegant
//Here, we set a String of "true" or "false" depending on the Boolean value
String theAnswer = (myBool ? 'true' : 'false');
//FIX ME!: Google "Apex Boolean Methods" to find how to convert the String named theAnswer to a Boolean
//and then assert that myBool equals theAnswer.
//Hint: Since we cannot directly compare a String to a Boolean, you have to create a new Boolean "b" with the conversion.
//Boolean b = ???;
//System.assertEquals();
//Most of the time we're comparing two things in our conditions
//You have to get used to typing "==" when you think "equals" in conditions
if(theAnswer.length() == 4){
System.debug('exactly 4 characters long');
} else if(theAnswer.length() >= 5){
System.debug('longer than 5 characters');
}
//FIX ME!: Now that you know about using "==" to compare values,
//rewrite this conditional block to handle different string values as well as null values.
String myPicklist = 'up';
/*
if(myPicklist){
System.debug('The value is up');
System.assertEquals('up',);
} else if(myPicklist){
System.debug('The value is down');
System.assertEquals('down',);
} else if(myPicklist){
System.debug('The picklist was empty');
System.assert(,);//Can you find an Apex String method to test if a string is null?
} else {
System.debug('The value was neither up nor down nor null');//what do you have to set myPicklist to to get this result?
System.assert? //How would you test that the string is not 'up', 'down' or null?
}
*/
//Any method that returns a boolean can be used in the condition clause.
//With Maps, a common pattern is to check for a value's existence before getting the value,
//and if it's not there, put it in the Map.
//prep a Map first so we have something to work with.
Map<String, Decimal> metricMap = new Map<String, Decimal>{'Kilo' => 1000, 'Milli' => .001};
if(metricMap.containsKey('Mega')){
System.debug('Mega is already there!');
System.debug(metricMap.get('Mega'));
} else {
metricMap.put('Mega', 1000000);
}
System.assertEquals(metricMap.get('Mega'), 1000000);
//FIX ME!: Add "Micro" to the metricMap so the following System Assert passes
if(metricMap.containsKey('Micro')){
//System.debug('Micro is already there!');
} else {
//metricMap.put('', .000001);
}
//System.assertEquals(,metricMap.get(''));
//let's prep some Booleans to play with comparison operators
Boolean x = true;
Boolean y = false;
//Conditionals can contain chains of variables (or boolean methods).
//Comparison operators follow the rules of logic you use everyday in Reports, Views and Formulas
if(x && y) System.debug('True AND False evaluates to False');
if(x && !y) System.debug('True AND NOT False evaluates to True');
if(x || y) System.debug('True OR False evaluates to True');
if(!x || y) System.debug('Not True OR False evaluates to False');
if(!(x && y)) System.debug('True AND False evaluates to False, BUT we re-evaluate that cumulative False to True with NOT(!)');
//FIX ME! Add in a third Boolean "z" to get these conditions to be true
Boolean z = true;
//if(x && y) System.debug('Now it evaluates to True!');
//if(!x || y) System.debug('Now it evaluates to True!');
////////////////
// FOR LOOPS //
////////////////
//For Loops allow you to work with multiple variables or objects
//There wasn't a good equivalent in the UI until Process Builder came along
//In Apex, they are an essential control for, well, everything!
//First variation: For each item in a List or Set, do something
Set<String> metricSet = metricMap.keySet();//Remember these are: ['Mega', 'Micro', 'Milli']
for(String s : metricSet){//for every string in metricSet do something...
System.debug(s);
}
//FIX ME! Now that we've looped through the keys in metricSet, loop through the values
List<Decimal> metricValues = metricMap.values();
//for(){
//system.debug();
//}
//Second variation: for each record returned by a SOQL query, do something.
for(User u : [Select Name from User]){
System.debug(u.Name);
}
//FIX ME! Write a for loop that retreive all the Profile Names and prints them in a System Debug
//Note that in Unit Tests without SeeAllData = True, Users and Profiles are still accessible along with a few other special Objects
//for(Profile p : []){
//System.debug();
//}
//Third variation: repeat the loop as many times as instructed
//This uses a special format common to many languages of establishing:
//1. An Entry Condition: Integer i = 0 (arbitrary, but 0 is useful when working with list indices)
//2. A Comparison: i < 5 (means "as long as")
//3. An Incrementor: i++ (add 1 to i each loop)
for(Integer i = 0 ; i < 5 ; i++){
System.debug('i now equals: ' + i);
}
List<String> names = new List<String>{'Kahlil', 'Daniela', 'Mohamed', 'Liu'};
String d = names[0];
//A very frequent pattern is repeating the loop for each item in a list using the list.size() method
for(Integer i = 0; i < names.size(); i++){
System.debug('Value at index ' + i + ' is ' + names[i]);//we can use i to retrieve each item in the list in order
}
//FIX ME! Make a for loop of 5 Integers that adds each Integer to itself
//use a system debug to output the result like "1 + 1 = 2"
//you have to use 3 variations on + to do this:
//1. + to concatentate two items
//2. + as a string to print out the plus sign (and later the equals sign)
//3. + as a mathematical operator to add the two Integers
//for(){
//System.debug();
//}
//Loop-di-Loop. You can embed loop within loops.
//prep some units of measurement
List<String> units = new List<String>{'meter', 'watt', 'gram'};
//The first iteration will loop through all the values in the inner loop first
//and then proceed on to the next item in the outer loop
for(String u : units){
for(String m : metricMap.keySet()){
System.debug('A ' + m + u + ' is ' + metricMap.get(m) + u + 's');//We use m to get the string and the metric multiplier from the Map!
}
}
//FIX ME! BIG CHALLENGE!!!
//Let's revise the FIX ME challenge from our SOQL lesson to use loops
//1. Create a Query to get all Contacts that are missing both a phone number and email address
//2. Create an empty collection to hold records we want to update
//3. Set the Contacts' Phone Number to the Account's Phone Number
//4. Put the records into your update collection
//5. Now, since we don't know the email, let's set CleanStatus to 'Skipped'
//6. Put the records into your update collection
//7. Use an "update" call to save the changes and commit them to the database
//8. Write a Unit Test to confirm it worked!
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment