Andy in the Cloud

From BBC Basic to Force.com and beyond…


4 Comments

FinancialForce Apex Common Community Updates

This short blog highlights a batch of new features recently merged to the FinancialForce Apex Common library aka fflib. In addition to the various Dreamforce and blog resources linked from the repo, fans of Trailhead can also find modules relating to the library here and here. But please read this blog first before heading out to the trails to hunt down badges! It’s really pleasing to see it continue to get great contributions so here goes…

Added methods for detecting changed records with given fields in the Domain layer (fflib_SObjectDomain)

First up is a great new optimization feature for your Domain class methods from Nathan Pepper aka MayTheSForceBeWithYou based on a suggestion by Daniel Hoechst. Where applicable its a good optimization practice to considering comparing the old and new values of fields relating to processing you are doing in your Domain methods to avoid unnecessary overheads. The new fflib_SObjectDomain.getChangedRecords method can be used as an alternative to the Records property to just the records that have changed based on the field list passed to the method.

// Returns a list of Account where the Name or AnnaulRevenue has changed
List<Account> accounts =
  (List<Account>) getChangedRecords(
     new List<SObjectField> { Account.Name, Account.AnnualRevenue });

Supporting EventBus.publish(list<SObject>) in Unit of Work (fflib_SObjectUnitOfWork)

Platform Events are becoming ever popular in many situations. If you regard them as logically part of the unit of work your code is performing, this enhancement from Chris Mail is for you! You can now register platform events to be sent based on various scenarios. Chris has also provided bulkified versions of the following methods, nice!

    /**
     * Register a newly created SObject (Platform Event) instance to be published when commitWork is called
     *
     * @param record A newly created SObject (Platform Event) instance to be inserted during commitWork
     **/
    void registerPublishBeforeTransaction(SObject record);
    /**
     * Register a newly created SObject (Platform Event) instance to be published when commitWork has successfully
     * completed
     *
     * @param record A newly created SObject (Platform Event) instance to be inserted during commitWork
     **/
    void registerPublishAfterSuccessTransaction(SObject record);
    /**
     * Register a newly created SObject (Platform Event) instance to be published when commitWork has caused an error
     *
     * @param record A newly created SObject (Platform Event) instance to be inserted during commitWork
     **/
    void registerPublishAfterFailureTransaction(SObject record);

Add custom DML for Application.UnitOfWork.newInstance call (fflib_Application)

It’s been possible for a while now to override the default means by which the fflib_SObjectUnitOfWork.commitWork method performs DML operations (for example if you wanted to do some additional pre/post processing or logging). However, if you have been using the Application class pattern to access your UOW (shorthand and helps with mocking) then this has not been possible. Thanks to William Velzeboer you can now get the best of both worlds!

fflib_SObjectUnitOfWork.IDML myDML = new MyCustomDMLImpl();
fflib_ISObjectUnitOfWork uow = Application.UnitOfWork.newIntance(myDML);

Added methods to Unit of Work to be able to register record for upsert (fflib_SObjectUnitOfWork)

Unit Of Work is a very popular class and receives yet another enhancement in this batch from Yury Bondarau. These two methods allow you to register records that will either be inserted or updated as automatically determined by the records having an Id populated or not, aka a UOW upsert.

    /**
     * Register a new or existing record to be inserted or updated during the commitWork method
     *
     * @param record An new or existing record
     **/
    void registerUpsert(SObject record);
    /**
     * Register a list of mix of new and existing records to be upserted during the commitWork method
     *
     * @param records A list of mix of existing and new records
     **/
    void registerUpsert(List&lt;SObject&gt; records);
    /**
     * Register an existing record to be deleted during the commitWork method
     *
     * @param record An existing record
     **/

Alleviates unit-test exception when Org’s email service is limited

Finally, long term mega fan of the library John Storey comes in with an ingenious fix to an Apex test failure which occurs when the org’s email deliverability’s ‘Access Level’ setting is not ‘All Email’. John leveraged an extensibility feature in the Unit Of Work to avoid the test being dependent on this org config all while not losing any code coverage, sweet!

Last but not least, thank you Christian Coleman for fixing those annoying typos in the docs! 🙂


7 Comments

Working with Apex Mocks Matchers and Unit Of Work

The Apex Mocks framework gained a new feature recently, namely Matchers. This new feature means that we can start verifying what records and their fields values are being passed to a mocked Unit Of Work more reliably and with a greater level of detail.

Since the Unit Of Work deals primarily with SObject types this does present some challenges to the default behaviour of Apex Mocks. Stephen Willcock‘s excellent blog points out the reasons behind this with some great examples. In addition prior to the matchers functionality, you could not verify your interest in a specific field value of a record, passed to registerDirty for example.

So first consider the following test code that does not use matchers.

	@IsTest
	private static void callingApplyDiscountShouldCalcDiscountAndRegisterDirty()
	{
		// Create mocks
		fflib_ApexMocks mocks = new fflib_ApexMocks();
		fflib_ISObjectUnitOfWork uowMock = new fflib_SObjectMocks.SObjectUnitOfWork(mocks);

		// Given
		Opportunity opp = new Opportunity(
			Id = fflib_IDGenerator.generate(Opportunity.SObjectType),
			Name = 'Test Opportunity',
			StageName = 'Open',
			Amount = 1000,
			CloseDate = System.today());
		Application.UnitOfWork.setMock(new List<Opportunity> { opp };);

		// When
		IOpportunities opps =
			Opportunities.newInstance(testOppsList);
		opps.applyDiscount(10, uowMock);

		// Then
		((fflib_ISObjectUnitOfWork)
			mocks.verify(uowMock, 1)).registerDirty(
				new Opportunity(
					Id = opp.Id,
					Name = 'Test Opportunity',
					StageName = 'Open',
					Amount = 900,
					CloseDate = System.today()));
	}

On the face of it, it looks like it should correctly verify that an updated Opportunity record with 10% removed from the Amount was passed to the Unit Of Work. But this fails with an assert claiming the method was not called. The main reason for this is its a new instance and this is not what the mock recorded. Changing it to verify with the test record instance works, but this only verifies the test record was passed, the Amount could be anything.

		// Then
		((fflib_ISObjectUnitOfWork)
			mocks.verify(uowMock, 1)).registerDirty(opp);

The solution is to use the new Matchers functionality for SObject’s. This time we can verify that a record was passed to the registerDirty method, that it was the one we expected by its Id and critically the correct Amount was set.

		// Then
		((fflib_ISObjectUnitOfWork)
			mocks.verify(uowMock, 1)).registerDirty(
				fflib_Match.sObjectWith(
					new Map<SObjectField, Object>{
						Opportunity.Id => opp.Id,
						Opportunity.Amount => 900} ));

There is also methods fflib_Match.sObjectWithName and fflib_Match.sObjectWithId as kind of short hands if you just want to check these specific fields. The Matcher framework is hugely powerful, with many more useful matchers. So i encourage you to take a deeper look David Frudd‘s excellent blog post here to learn more.

If you want to know more about how Apex Mocks integrates with the Apex Enterprise Patterns as shown in the example above, refer to this two part series here.


11 Comments

Unit Testing, Apex Enterprise Patterns and ApexMocks – Part 2

In Part 1 of this blog series i introduced a new means of applying true unit testing to Apex code leveraging the Apex Enterprise Patterns. Covering the differences between true unit testing vs integration testing and how the lines can get a little blurred when writing Apex test methods.

If your following along you should be all set to start writing true unit tests against your controller, service and domain classes. Leveraging the inbuilt dependency injection framework provided by the Application class introduced in the last blog. By injecting mock implementations of service, domain, selector and unit of work classes accordingly.

What are Mock classes and why do i need them?

Depending on the type of class your unit testing you’ll need to mock different dependencies so that you don’t have to worry about the data setup of those classes while your busy putting your hard work in to testing your specific class.

Unit Testing

In object-oriented programming, mock objects are simulated objects that mimic the behavior of real objects in controlled ways. A programmer typically creates a mock object to test the behavior of some other object, in much the same way that a car designer uses a crash test dummy to simulate the dynamic behavior of a human in vehicle impacts. Wikipedia.

In this blog we are going to focus on an example unit test method for a Service, which requires that we mock the unit of work, selector and domain classes it depends on (unit tests for these classes will of course be written as well). Lets take a look first at the overall test method then break it down bit by bit. The following test method makes no SOQL queries or DML to accomplish its goal of testing the service layer method.

	@IsTest
	private static void callingServiceShouldCallSelectorApplyDiscountInDomainAndCommit()
	{
		// Create mocks
		fflib_ApexMocks mocks = new fflib_ApexMocks();
		fflib_ISObjectUnitOfWork uowMock = new fflib_SObjectMocks.SObjectUnitOfWork(mocks);
		IOpportunities domainMock = new Mocks.Opportunities(mocks);
		IOpportunitiesSelector selectorMock = new Mocks.OpportunitiesSelector(mocks);

		// Given
		mocks.startStubbing();
		List<Opportunity> testOppsList = new List<Opportunity> {
			new Opportunity(
				Id = fflib_IDGenerator.generate(Opportunity.SObjectType),
				Name = 'Test Opportunity',
				StageName = 'Open',
				Amount = 1000,
				CloseDate = System.today()) };
		Set<Id> testOppsSet = new Map<Id, Opportunity>(testOppsList).keySet();
		mocks.when(domainMock.sObjectType()).thenReturn(Opportunity.SObjectType);
		mocks.when(selectorMock.sObjectType()).thenReturn(Opportunity.SObjectType);
		mocks.when(selectorMock.selectByIdWithProducts(testOppsSet)).thenReturn(testOppsList);
		mocks.stopStubbing();
		Decimal discountPercent = 10;
		Application.UnitOfWork.setMock(uowMock);
		Application.Domain.setMock(domainMock);
		Application.Selector.setMock(selectorMock);

		// When
		OpportunitiesService.applyDiscounts(testOppsSet, discountPercent);

		// Then
		((IOpportunitiesSelector)
			mocks.verify(selectorMock)).selectByIdWithProducts(testOppsSet);
		((IOpportunities)
			mocks.verify(domainMock)).applyDiscount(discountPercent, uowMock);
		((fflib_ISObjectUnitOfWork)
			mocks.verify(uowMock, 1)).commitWork();
	}

First of all, you’ll notice the test method name is a little longer than you might be used to, also the general layout of the test splits code into Given, When and Then blocks. These conventions help add some documentation, readability and consistency to test methods, as well as helping you focus on what it is your testing and assuming to happen. The convention is one defined by Martin Fowler, you can read more about GivenWhenThen here. The test method name itself, stems from a desire to express the behaviour the test is confirming.

Generating and using Mock Classes

UPDATE: Since the Apex Stub API was released you do not need this, see here!

The Java based Mockito framework leverages the Java runtimes capability to dynamically create mock implementations. However the Apex runtime does not have any support for this. Instead ApexMocks uses source code generation to generate the mock classes it requires based on the interfaces you defined in my earlier post.

The patterns library also comes with its own mock implementation of the Unit of Work for you to use, as well as some base mock classes for your selectors and domain mocks (made know to the tool below). The following code at the top of the test method creates the necessary mock instances that will be configured and injected into the execution.

// Create mocks
fflib_ApexMocks mocks = new fflib_ApexMocks();
fflib_ISObjectUnitOfWork uowMock = new fflib_SObjectMocks.SObjectUnitOfWork(mocks);
IOpportunities domainMock = new Mocks.Opportunities(mocks);
IOpportunitiesSelector selectorMock = new Mocks.OpportunitiesSelector(mocks);

To generate the Mocks class used above use the ApexMocks Generator, you can run it via the Ant tool. The apex-mocks-generator-3.1.2.jar file can be downloaded from the ApexMocks repo here.

<?xml version="1.0" encoding="UTF-8"?>
<project name="Apex Commons Sample Application" default="generate.mocks" basedir=".">

	<target name="generate.mocks">
		<java classname="com.financialforce.apexmocks.ApexMockGenerator">
			<classpath>
				<pathelement location="${basedir}/bin/apex-mocks-generator-3.1.2.jar"/>
			</classpath>
			<arg value="${basedir}/fflib-sample-code/src/classes"/>
			<arg value="${basedir}/interfacemocks.properties"/>
			<arg value="Mocks"/>
			<arg value="${basedir}/fflib-sample-code/src/classes"/>
		</java>
	</target>

</project>

You can configure the output of the tool using a properties file (you can find more information here).

IOpportunities=Opportunities:fflib_SObjectMocks.SObjectDomain
IOpportunitiesSelector=OpportunitiesSelector:fflib_SObjectMocks.SObjectSelector
IOpportunitiesService=OpportunitiesService

The generated mock classes are contained as inner classes in the Mocks.cls class and also implement the interfaces you define, just as the real classes do. You can choose to add the above Ant tool call into your build scripts or just simply retain the class in your org refreshing it by re-run the tool whenever your interfaces change.

/* Generated by apex-mocks-generator version 3.1.2 */
@isTest
public class Mocks
{
	public class OpportunitiesService
		implements IOpportunitiesService
	{
		// Mock implementations of the interface methods...
	}

	public class OpportunitiesSelector extends fflib_SObjectMocks.SObjectSelector
		implements IOpportunitiesSelector
	{
		// Mock implementations of the interface methods...
	}

	public class Opportunities extends fflib_SObjectMocks.SObjectDomain
		implements IOpportunities
	{
		// Mock implementations of the interface methods...
	}
}

Mocking method responses

Mock classes are dumb by default, so of course you cannot inject them into the upcoming code execution and expect them to work. You have to tell them how to respond when called. They will however record for you when their methods have been called for you to check or assert later. Using the framework you can tell a mock method what to return or exceptions to throw when the class your testing calls it.

So in effect you can teach them to emulate their real counter parts. For example when a Service method calls a Selector method it can return some in memory records as apposed to having to have them setup on the database. Or when the unit of work is used it will record method invocations as apposed to writing to the database.

Here is an example of configuring a Selector mock method to return test record data. Note that you also need to inform the Selector mock what type of SObject it relates to, this is also the case when mocking the Domain layer. Finally be sure to call startStubbing and stopStubbing between your mock configuration code. You can read much more about the ApexMocks API here, which resembles the Java Mockito API as well.

// Given
mocks.startStubbing();
List<Opportunity> testOppsList = new List<Opportunity> {
	new Opportunity(
		Id = fflib_IDGenerator.generate(Opportunity.SObjectType),
		Name = 'Test Opportunity',
		StageName = 'Open',
		Amount = 1000,
		CloseDate = System.today()) };
Set<Id> testOppsSet = new Map<Id, Opportunity>(testOppsList).keySet();
mocks.when(domainMock.sObjectType()).thenReturn(Opportunity.SObjectType);
mocks.when(selectorMock.sObjectType()).thenReturn(Opportunity.SObjectType);
mocks.when(selectorMock.selectByIdWithProducts(testOppsSet)).thenReturn(testOppsList);
mocks.stopStubbing();

TIP: If you want to mock sub-select queries returned from a selector take a look at this.

Injecting your mock implementations

Finally before you call the method your wanting to test, ensure you have injected the mock implementations. So that the calls to the Application class factory methods will return your mock instances over the real implementations.

Application.UnitOfWork.setMock(uowMock);
Application.Domain.setMock(domainMock);
Application.Selector.setMock(selectorMock);

Testing your method and asserting the results

Calling your method to test is a straight forward as you would expect. If it returns values or modifies parameters you can assert those values. However the ApexMocks framework also allows you to add further behavioural assertions that add further confidence the code your testing is working the way it should. In this case we are wanting to assert or verify (to using mocking speak) the correct information was passed onto the domain and selector classes.

// When
OpportunitiesService.applyDiscounts(testOppsSet, discountPercent);

// Then
((IOpportunitiesSelector)
	mocks.verify(selectorMock)).selectByIdWithProducts(testOppsSet);
((IOpportunities)
	mocks.verify(domainMock)).applyDiscount(discountPercent, uowMock);
((fflib_ISObjectUnitOfWork)
	mocks.verify(uowMock, 1)).commitWork();

TIP: You can verify method calls have been made and also how many times. For example checking a method is only called a specific number of times can help add some level of performance and optimisation checking into your tests.

Summary

The full API for ApecMocks is outside the scope of this blog series, and frankly Paul Hardaker and Jessie Altman have done a much better job, take a look at the full list of documentation links here. Finally keep in mind my comments at the start of this series, this is not to be seen as a total alternative to traditional Apex test method writing. Merely another option to consider when your wanting a more focused means to test specific methods in more varied ways without incurring the development and execution costs of having to setup all of your applications data in each test method.


9 Comments

Unit Testing, Apex Enterprise Patterns and ApexMocks – Part 1

If you attended my Advanced Apex Enterprise Patterns session at Dreamforce 2014 you’ll have heard me highlight the different between Apex tests that are either written as true unit test vs those written in a way that more resembles an integration test. As Paul Hardaker (ApexMocks author) once pointed out to me, technically the reality is Apex developers often only end up writing only integration tests.

Lets review Wikipedia’s definition of unit tests

Intuitively, one can view a unit as the smallest testable part of an application. In procedural programming, a unit could be an entire module, but it is more commonly an individual function or procedure. In object-oriented programming, a unit is often an entire interface, such as a class, but could be an individual method. Unit tests are short code fragments created by programmers or occasionally by white box testers during the development process

Does this describe an Apex Test you have written recently?

Lets review what Apex tests typically require us to perform…

  • Setup of application data for every test method
  • Executes the more code than we care about testing at the time
  • Tests often not very varied enough, as they can take a long time to run!

Does the following Wikipedia snippet describing integration tests more accurately describe this?

Integration testing (sometimes called integration and testing, abbreviated I&T) is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing

The challenge with writing true unit tests in Apex can also leave those wishing to follow practices like TDD struggling due to the lack of dependency injection and mocking support in the Apex runtime. We start to desire mocking support such as what we find for example in Java’s Mockito (the inspiration behind ApexMocks).

The lines between unit vs integration testing and which we should use and when can get blurred since Force.com does need Apex tests to invoke Apex Triggers for coverage (requiring actual test integration with the database) and if your using Workflows a lot you may want the behaviour of these reflected in your tests. So one cannot completely move away from writing integration tests of course. But is there a better way for us to regain some of the benefits other platforms enjoy in this area for the times we feel it would benefit us?

Problems writing Unit Tests for complex code bases…

Integration TestingThe problem is a true unit tests aim to test a small unit of the code, typically a specific method. However if this method ends up querying the database we need to have inserted those records prior to calling the method and then assert the records afterwards. If your familiar with Apex Enterprise Patterns, you’ll recognise the following separation of concerns in this diagram which shows clearly what code might be executed in a controller test for example.

For complex applications this approach per test can be come quite an overhead before you even get to call your controller method and assert the results! Lets face it, as we have to wait longer and longer for such tests, this inhibits our desire to write further more complex tests that may more thoroughly test the code with different data combinations and use cases.

 

 

 

What if we could emulate the database layer somehow?

Well those of you familiar with Apex Enterprise Patterns will know its big on separation of concerns. Thus aspects such as querying the database and updating it are encapsulated away in so called Selectors and the Unit Of Work. Just prior to Dreamforce 2014, the patterns introduced the Application class, this provides a single application wide means to access the Service, Domain, Selector and Unit Of Work implementations as apposed to directly instantiating them.

If you’ve been reading my book, you’ll know that this also provides access to new Object Orientated Programming possibilities, such as polymorphism between the Service layer and Domain layer, allowing for a functional frameworks and greater reuse to be constructed within the code base.

In this two part blog series, we are focusing on the role of the Application class and its setMock methods. These methods, modelled after the platforms Test.setMock method (for mocking HTTP comms), provide a means to mock the core architectural layers of an application which is based on the Apex Enterprise Patterns. By allowing mocking in these areas, we can see that we can write unit tests that focus only on the behaviour of the controller, service or domain class we are testing.

Unit Testing

Preparing your Service, Domain and Selector classes for mocking

As described in my Dreamforce 2014 presentation, Apex Interfaces are key to implementing mocking. You must define these in order to allow the mocking framework to substitute dynamically different implementations. The patterns library also provides base interfaces that reflect the base class methods for the Selector and Domain layers. The sample application contains a full example of these interfaces and how they are applied.


// Service layer interface

public interface IOpportunitiesService
{
	void applyDiscounts(Set<ID> opportunityIds, Decimal discountPercentage);

	Set<Id> createInvoices(Set<ID> opportunityIds, Decimal discountPercentage);

	Id submitInvoicingJob();
}

// Domain layer interface

public interface IOpportunities extends fflib_ISObjectDomain
{
	void applyDiscount(Decimal discountPercentage, fflib_ISObjectUnitOfWork uow);
}

// Selector layer interface

public interface IOpportunitiesSelector extends fflib_ISObjectSelector
{
	List<Opportunity> selectByIdWithProducts(Set<ID> idSet);
}

First up apply the Domain class interfaces as follows…


// Implementing Domain layer interface

public class Opportunities extends fflib_SObjectDomain
	implements IOpportunities {

	// Rest of the class
}

Next is the Service class, since the service layer remains stateless and global, i prefer to retain the static method style. Since you cannot apply interfaces to static methods, i use the following convention, though I’ve seen others with inner classes. First create a new class something like OpportunitiesServiceImpl, copy the implementation of the existing service into it and remove the static modifier from the method signatures before apply the interface. The original service class then becomes a stub for the service entry point.


// Implementing Service layer interface

public class OpportunitiesServiceImpl
	implements IOpportunitiesService
{
	public void applyDiscounts(Set<ID> opportunityIds, Decimal discountPercentage)
	{
		// Rest of the method...
	}

	public Set<Id> createInvoices(Set<ID> opportunityIds, Decimal discountPercentage)
	{
		// Rest of the method...
	}

	public Id submitInvoicingJob()
	{
		// Rest of the method...
	}
}

// Service layer stub

global with sharing class OpportunitiesService
{
	global static void applyDiscounts(Set<ID> opportunityIds, Decimal discountPercentage)
	{
		service().applyDiscounts(opportunityIds, discountPercentage);
	}

	global static Set<Id> createInvoices(Set<ID> opportunityIds, Decimal discountPercentage)
	{
		return service().createInvoices(opportunityIds, discountPercentage);
	}

	global static Id submitInvoicingJob()
	{
		return service().submitInvoicingJob();
	}	

	private static IOpportunitiesService service()
	{
		return new OpportunitiesServiceImpl();
	}
}

Finally the Selector class, like the Domain class is a simple matter of applying the interface.

public class OpportunitiesSelector extends fflib_SObjectSelector
	implements IOpportunitiesSelector
{
	// Rest of the class
}

Implementing Application.cls

Once you have defined and implemented your interfaces you need to ensure there is a means to switch at runtime the different implementations of them, between the real implementation and a the mock implementation as required within a test context. To do this a factory pattern is applied for calling logic to obtain the appropriate instance. Define the Application class as follows, using the factory classes provided in the library. Also note that the Unit Of Work is defined here in a single maintainable place.

public class Application
{
	// Configure and create the UnitOfWorkFactory for this Application
	public static final fflib_Application.UnitOfWorkFactory UnitOfWork =
		new fflib_Application.UnitOfWorkFactory(
				new List<SObjectType> {
					Invoice__c.SObjectType,
					InvoiceLine__c.SObjectType,
					Opportunity.SObjectType,
					Product2.SObjectType,
					PricebookEntry.SObjectType,
					OpportunityLineItem.SObjectType });	

	// Configure and create the ServiceFactory for this Application
	public static final fflib_Application.ServiceFactory Service =
		new fflib_Application.ServiceFactory(
			new Map<Type, Type> {
					IOpportunitiesService.class => OpportunitiesServiceImpl.class,
					IInvoicingService.class => InvoicingServiceImpl.class });

	// Configure and create the SelectorFactory for this Application
	public static final fflib_Application.SelectorFactory Selector =
		new fflib_Application.SelectorFactory(
			new Map<SObjectType, Type> {
					Opportunity.SObjectType => OpportunitiesSelector.class,
					OpportunityLineItem.SObjectType => OpportunityLineItemsSelector.class,
					PricebookEntry.SObjectType => PricebookEntriesSelector.class,
					Pricebook2.SObjectType => PricebooksSelector.class,
					Product2.SObjectType => ProductsSelector.class,
					User.sObjectType => UsersSelector.class });

	// Configure and create the DomainFactory for this Application
	public static final fflib_Application.DomainFactory Domain =
		new fflib_Application.DomainFactory(
			Application.Selector,
			new Map<SObjectType, Type> {
					Opportunity.SObjectType => Opportunities.Constructor.class,
					OpportunityLineItem.SObjectType => OpportunityLineItems.Constructor.class,
					Account.SObjectType => Accounts.Constructor.class,
					DeveloperWorkItem__c.SObjectType => DeveloperWorkItems.class });
}

Using Application.cls

If your adapting an existing code base, be sure to leverage the Application class factory methods in your application code, seek out code which is explicitly instantiating the classes of your Domain, Selector and Unit Of Work usage. Note you don’t need to worry about Service class references, since this is now just a stub entry point.

The following code shows how to wrap the Application factory methods using convenience methods that can help avoid repeated casting to the interfaces, it’s up to you if you adopt these or not, the effect is the same regardless. Though the modification the service method shown above is required.


// Service class Application factory usage

global with sharing class OpportunitiesService
{
	private static IOpportunitiesService service()
	{
		return (IOpportunitiesService) Application.Service.newInstance(IOpportunitiesService.class);
	}
}

// Domain class Application factory helper

public class Opportunities extends fflib_SObjectDomain
	implements IOpportunities
{
	public static IOpportunities newInstance(List<Opportunity> sObjectList)
	{
		return (IOpportunities) Application.Domain.newInstance(sObjectList);
	}
}

// Selector class Application factory helper

public with sharing class OpportunitiesSelector extends fflib_SObjectSelector
	implements IOpportunitiesSelector
{
	public static IOpportunitiesSelector newInstance()
	{
		return (IOpportunitiesSelector) Application.Selector.newInstance(Opportunity.SObjectType);
	}
}

With these methods in place reference them and those on the Application class as shown in the following example.

public class OpportunitiesServiceImpl
	implements IOpportunitiesService
{
	public void applyDiscounts(Set<ID> opportunityIds, Decimal discountPercentage)
	{
		// Create unit of work to capture work and commit it under one transaction
		fflib_ISObjectUnitOfWork uow = Application.UnitOfWork.newInstance();

		// Query Opportunities
		List<Opportunity> oppRecords =
			OpportunitiesSelector.newInstance().selectByIdWithProducts(opportunityIds);

		// Apply discount via Opportunties domain class behaviour
		IOpportunities opps = Opportunities.newInstance(oppRecords);
		opps.applyDiscount(discountPercentage, uow);

		// Commit updates to opportunities
		uow.commitWork();
	}
}

The Selector factory does carry some useful generic helpers, these will internally utilise the Selector classes as defined on the Application class definition above.


List<Opportunity> opps =
   (List<Opportunity>) Application.Selector.selectById(myOppIds);

List<Account> accts =
   (List<Account>) Application.Selector.selectByRelationship(opps, Account.OpportunityId);

Summary and Part Two

In this blog we’ve looked at how to defined and apply interfaces between your service, domain, selector and unit of work dependencies. Using a factory pattern through the indirection of the Application class we have implemented an injection framework within the definition of these enterprise application separation of concerns.

I’ve seen dependency injection done via constructor injection, my personal preference is to use the approach shown in this blog. My motivation for this lies with the fact that these pattern layers are well enough known throughout the application code base and the Application class supports other facilities such as polymorphic instantiation of domain classes and helper methods as shown above on the Selector factory.

In the second part of this series we will look at how to write true unit tests for your controller, service and domain classes, leveraging the amazing ApexMocks library! If in the meantime you wan to get a glimpse of what this might look like take a wonder through the Apex Enterprise Patterns sample application tests here and here.


// Provide a mock instance of a Unit of Work
Application.UnitOfWork.setMock(uowMock);

// Provide a mock instance of a Domain class
Application.Domain.setMock(domainMock);

// Provide a mock instance of a Selector class
Application.Selector.setMock(selectorMock);

// Provide a mock instance of a Service class
Application.Service.setMock(IOpportunitiesService.class, mockService);