Tutorial
...
Nue on Salesforce
Apex Test Utils
50 min
nue offers a suite of global apex test utility classes that empower apex admins to efficiently generate quotes, orders, line buckets, and other essential data structures for apex tests these utilities help ensure sufficient code coverage, a requirement by salesforce when deploying change sets containing custom apex classes from sandbox to production seed system settings nue’s system settings and object mapping configurations are stored in salesforce custom settings, which are not accessible within the apex test context by default however, these settings are required for creating quotes, orders, and subscriptions to support testing, nue provides the following apex global methods to seed these settings within test classes we recommend invoking these methods before creating nue quotes and orders within apex test classes ruby rubysettingservice globalseedsystemsettings(); ruby rubysettingservice globalseedobjectmappings(); builders and objectcreator in the apex test utilities, we provide a set of builder classes quotebuilder, orderbuilder, linebucketbuilder, and ``linepricetagbuilder that enable apex developers to efficiently construct quotes, orders, and line buckets with the necessary fields these builders automatically populate default values for non required fields while ensuring compliance with the additional business logic required for nue to function correctly following the builder pattern , these classes focus on creating structured data that aligns with nue’s business logic additionally, we provide an objectcreator class that takes the in memory data structures built using the builders and persists them as actual quotes, orders, and line buckets apex developers can leverage objectcreator alongside the builders to streamline test development and accelerate the testing process builder classes nue offers the following global builder classes to help apex developers efficiently create in memory data structures for quotes, orders, and line buckets, enabling faster test development ruby quotebuilder ruby orderbuilder ruby linebucketbuilder ruby linepricetagbuilder please note that these builder classes do not persist objects apex developers can use the ruby objectcreator test utility class to create and persist quotes, orders, and line buckets the following shows an example of using objectcreator and quotebuilder to create a new quote with quote line items java quote testquote = ruby objectcreator createquotes(new list\<ruby quotebuilder>{ new ruby quotebuilder() setname('testquote') setcontactid(testcontact id) setopportunityid(testopportunity id) setquotelines(new list\<ruby quotelinebuilder>{ new ruby quotelinebuilder() setpricebookentry(testpricebookentries\[0]) setquantity(5 0), new ruby quotelinebuilder() setpricebookentry(testpricebookentries\[1]) setquantity(5 0) }) })\[0]; each builder class includes a global method that retrieves the in memory sobject, allowing apex developers to add additional data (e g , custom fields) before persisting the object for example, in quotebuilder global class, nue provides the following global method global quote getsobject() { return this quotesobject; } apex developers can get a reference to the quote sobject from the builder ruby quotebuilder quotebuilder = new ruby quotebuilder() setname('testquote'); quote testquote = quotebuilder getsobject(); testquote opportunityid = testopportunityid; objectcreator class overview the ruby objectcreator class is a global apex utility designed for creating various salesforce objects efficiently for testing purposes it provides static methods to generate records for uom c , product2 , pricebookentry , quote , quotelineitem , order , and related entities this utility is useful for setting up test data in apex test classes to validate business logic this class is designed only for test environments and should not be used in production methods 1\ createuom description creates and inserts a ruby uom c record method signature global static ruby uom c createuom(string roundingmode, string termdimension, string quantitydimension, string name, integer decimalscale) parameters roundingmode the rounding mode for the unit of measure termdimension the term dimension quantitydimension the quantity dimension name the name of the uom decimalscale the decimal scale of the uom returns ruby uom c the created uom record 2\ createproduct description creates and inserts a product2 record method signature global static product2 createproduct(string name, id defaultuomid, id referenceproductid) parameters name the product name defaultuomid the default uom id referenceproductid (optional) reference product id returns product2 the created product record 3\ createpricebookentry description creates and inserts a pricebookentry record method signature global static pricebookentry createpricebookentry(id productid, id pricebookid, id uomid, integer listprice) parameters productid the associated product id pricebookid the price book id uomid the uom id listprice the list price returns pricebookentry the created price book entry 4\ createquotes description creates multiple quote records from a list of quotebuilder objects method signature global static list\<quote> createquotes(list\<ruby quotebuilder> quotebuilders) parameters quotebuilders a list of quotebuilder objects returns list\<quote> the created quote records 5\ createquotelinebuckets description creates and inserts ruby linebucket c records for quotes method signature global static list\<ruby linebucket c> createquotelinebuckets(list\<linebucketbuilder> linebucketbuilders) parameters linebucketbuilders a list of linebucketbuilder objects returns list\<ruby linebucket c> the created line bucket records 6\ createquotelines description creates and inserts quotelineitem records method signature global static list\<quotelineitem> createquotelines(list\<quotelinebuilder> quotelinebuilders) parameters quotelinebuilders a list of quotelinebuilder objects returns list\<quotelineitem> the created quote line records 7\ createorders description creates multiple order records from a list of orderbuilder objects method signature global static list\<order> createorders(list\<orderbuilder> orderbuilders) parameters orderbuilders a list of orderbuilder objects returns list\<order> the created order records 8\ createorderitembuckets description creates and inserts ruby linebucket c records for orders method signature global static list\<ruby linebucket c> createorderitembuckets(list\<ruby linebucketbuilder> linebucketbuilders) parameters linebucketbuilders a list of linebucketbuilder objects returns list\<ruby linebucket c> the created order line bucket records 9\ createorderitems description creates and inserts orderitem records method signature global static list\<orderitem> createorderitems(list\<orderitembuilder> orderitembuilders) parameters orderitembuilders a list of orderitembuilder objects returns list\<orderitem> the created order item records example tests let’s start by reviewing some test examples create initial quotes and orders the following apex test class shows how apex developers and use quotebuilder, orderbuilder, and objectcreator to quickly create quotes and orders associated with contacts and opportunities @istest public with sharing class nueexampletest { private static account testsalesaccount; private static account testbillingaccount; private static contact testcontact; private static opportunity testopportunity; @testsetup static void setup() { testsalesaccount = new account(name = 'testsalesaccount'); insert testsalesaccount; testbillingaccount = new account( name = 'testbillingaccount', ruby salesaccount c = testsalesaccount id ); insert testbillingaccount; testcontact = new contact( firstname = 'john', lastname = 'doe', accountid = testsalesaccount id ); insert testcontact; testopportunity = new opportunity( name = 'testopportunity', accountid = testsalesaccount id, stagename = 'prospect', closedate = date newinstance(2022, 1, 1) ); insert testopportunity; } @istest static void testcreatequote() { testcontact = \[select id, accountid, firstname, lastname from contact]; testopportunity = \[select id, accountid from opportunity]; list\<pricebookentry> testpricebookentries = createproductsandrelatedobjects( 2 ); quote testquote = ruby objectcreator createquotes( new list\<ruby quotebuilder>{ new ruby quotebuilder() setname('testquote') setcontactid(testcontact id) setopportunityid(testopportunity id) setquotelines( new list\<ruby quotelinebuilder>{ new ruby quotelinebuilder() setpricebookentry(testpricebookentries\[0]) setquantity(5 0), new ruby quotelinebuilder() setpricebookentry(testpricebookentries\[1]) setquantity(5 0) } ) } )\[0]; system assertequals( 2, \[select count() from quotelineitem where quoteid = \ testquote id], 'the quote should have 2 lines ' ); system assertnotequals(null, testquote id, 'quote id should not be null'); } @istest static void testcreateorder() { testcontact = \[select id, accountid, firstname, lastname from contact]; testopportunity = \[select id, accountid from opportunity]; list\<pricebookentry> testpricebookentries = createproductsandrelatedobjects( 2 ); order testorder = ruby objectcreator createorders( new list\<ruby orderbuilder>{ new ruby orderbuilder() setname('testorder') setaccountid(testcontact accountid) setopportunityid(testopportunity id) setorderitems( new list\<ruby orderitembuilder>{ new ruby orderitembuilder() setpricebookentry(testpricebookentries\[0]) setquantity(5 0), new ruby orderitembuilder() setpricebookentry(testpricebookentries\[1]) setquantity(5 0) } ) } )\[0]; system assertequals( 2, \[select count() from orderitem where orderid = \ testorder id], 'the order should have 2 lines ' ); system assertnotequals(null, testorder id, 'order id should not be null'); } private static list\<pricebookentry> createproductsandrelatedobjects( integer numberofproducts ) { list\<pricebookentry> pricebookentries = new list\<pricebookentry>(); list\<product2> products = new list\<product2>(); for (integer i = 0; i < numberofproducts; i++) { ruby uom c uom = ruby objectcreator createuom('up', 'month', 'user', 'user/month' + i, 1); product2 product = ruby objectcreator createproduct('prod' + i, uom id, null); products add(product); pricebookentries add( ruby objectcreator createpricebookentry( product id, test getstandardpricebookid(), uom id, 100 ) ); } return pricebookentries; } } # generate subscription and create change quote this test class validates the update quantity change quote process for existing subscriptions using the globalchangeorderservice it simulates a complete lifecycle scenario, including creating a test account and opportunity creating a product , pricebook entry , and associated order using ruby objectcreator test util methods activating the order to trigger the creation of a subscription (ruby subscription c) creating a second “change” opportunity to test the update quantity flow mocking any external callouts using a private httpcalloutmock class verifying that the change quote is created successfully and no exceptions occur @istest public class updatequantitychangequotetest { @istest static void createsubscription() { // seed default system settings and object mappings ruby rubysettingservice globalseedsystemsettings(); ruby rubysettingservice globalseedobjectmappings(); // ─────────────── step 1 create account and initial opportunity ─────────────── account testaccount = new account(name = 'test account'); insert testaccount; opportunity initialopp = new opportunity( name = 'initial order opportunity', stagename = 'prospecting', closedate = date today() adddays(30), accountid = testaccount id ); insert initialopp; system debug('✔ created account ' + testaccount id); system debug('✔ created opportunity ' + initialopp id); // ─────────────── step 2 create product and pricebook entry ─────────────── pricebookentry pbe = createproductsandrelatedobjects(1)\[0]; // ─────────────── step 3 create and activate order ─────────────── order testorder = ruby objectcreator createorders(new list\<ruby orderbuilder>{ new ruby orderbuilder() setname('testorder') setaccountid(testaccount id) setopportunityid(initialopp id) setorderitems(new list\<ruby orderitembuilder>{ new ruby orderitembuilder() setpricebookentry(pbe) setquantity(5 0) }) })\[0]; upsert testorder; testorder status = 'activated'; upsert testorder; system debug('✔ activated order ' + testorder id); // ─────────────── step 4 retrieve generated subscription ─────────────── ruby subscription c subscription = \[ select id, name from ruby subscription c where ruby product c = \ pbe product2id limit 1 ]; string subscriptionnumber = subscription name; system debug('✔ subscription number ' + subscriptionnumber); // ─────────────── step 5 create change opportunity ─────────────── opportunity changeopp = new opportunity( name = 'true up test opportunity', stagename = 'prospecting', closedate = date today() adddays(30), accountid = testaccount id ); insert changeopp; // ─────────────── step 6 set mock and call true up logic ─────────────── test setmock(httpcalloutmock class, new myhttpmock()); test starttest(); createquote(changeopp id, date today(), 10, subscriptionnumber); test stoptest(); } // ─────────────────────── private inner mock class ─────────────────────── private class myhttpmock implements httpcalloutmock { public httpresponse respond(httprequest req) { httpresponse res = new httpresponse(); res setheader('content type', 'application/json'); res setbody('{"status" "ok"}'); res setstatuscode(200); return res; } } // ─────────────────────── helper create products & pricebook entries ─────────────────────── private static list\<pricebookentry> createproductsandrelatedobjects(integer numberofproducts) { list\<pricebookentry> pricebookentries = new list\<pricebookentry>(); for (integer i = 0; i < numberofproducts; i++) { ruby uom c uom = ruby objectcreator createuom('up', 'month', 'user', 'user/month' + i, 1); product2 product = ruby objectcreator createproduct('prod' + i, uom id, null); product family = 'recurringservices'; upsert product; pricebookentries add( ruby objectcreator createpricebookentry( product id, test getstandardpricebookid(), uom id, 100 ) ); } return pricebookentries; } // ─────────────────────── helper create quote via ruby globalchangeorderservice ─────────────────────── private static void createquote(id opportunityid, date changedate, integer quantity, string subscriptionname) { string msg = 'message = '; try { ruby globalchangeorderoptions options = new ruby globalchangeorderoptions(ruby globalchangeorderproceedoption createquote); options activateorder = false; options opportunityid = opportunityid; // assemble change requests list\<ruby globalassetchangerequest> changerequests = new list\<ruby globalassetchangerequest>(); ruby globalupdatequantityrequest updatequantityrequest = new ruby globalupdatequantityrequest(); updatequantityrequest assetnumber = subscriptionname; updatequantityrequest startdate = changedate; updatequantityrequest quantity = quantity; changerequests add(updatequantityrequest); // execute change order ruby globalchangeorderservice service = new ruby globalchangeorderservice(); ruby globalchangeorderresult result = service changeorder(new ruby globalchangeorder(options, changerequests)); if (result success) { msg += 'quote created successfully'; } else { for (ruby globalchangeorderresult message message result messages) { msg += message message + ' '; } } } catch (exception e) { system debug('error ' + e getmessage()); system debug('stack trace ' + e getstacktracestring()); } system debug(msg); } }
🤔
Have a question?
Get answers fast with Nue’s intelligent AI, expert support team, and a growing community of users - all here to help you succeed.
To ask a question or participate in discussions, you'll need to authenticate first.