November 10, 2016
Why we need a Builder Pattern for our test data
Properly testing Apex code is a necessary and important element of Salesforce development. To do so requires building test data that grows in complexity with the code you are testing.
The Force.com platform gives us a pretty simple way to create sObject Data for Unit Tests. With the dynamic constructors that sObjects are equipped with, we can create records with populated fields.
How is it then that so many people struggle to create good test data?
This pattern does not hide the complexity of the test data creation from the actual test method / class:
Order__c someOrder = new Order__c( OrderNumber__c = '12345', OrderSummary__c = 'Some Summary' ); insert someOrder; OrderItem__c someItem = new OrderItem( Order__c = someOrder.Id, Item__c = 'Table' ); insert someItem; ShippingAddress__c someAddress = new ShippingAddress__c( Order__c = someOrder.Id, Street__c = 'Some Street', City__c = 'Some City', State__c = 'Some State', Country__c = 'Some Country' ); insert someAddress;
Now, there are several issues with the above pattern: - First off, we need to know all this information for every test method or class we want to create this data for. - We also need to know which fields need to be populated for our initial insert. - As well as which fields we need for our actual test.
So at some point, we start to abstract this knowledge away to make our tests clearer and more readable.
This is where the Factory Pattern comes in…
The Factory Pattern is used inside the Force.com community to create abstract test data in an easy, convenient and re-usable way. For example, the above test data could be generated by one line:
Seems nice enough, right?
But now let’s take this pattern one step further. Let’s create a more specific test data: - [ ] an order with specific items and specific addresses. What do we do?
TestDataFactory.createSomeOrder(); TestDataFactory.createTableAndChairsOrder(); TestDataFactory.createTableAndChairsOrderWithGermanShippingAddress(); TestDataFactory.createChairsAndLampsOrder();
Over time, our factory classes tend to get bloated, messy and very hard to maintain to a high coding standard.
In the example above, what if we want to create an order with tables, chairs and lamps with a generic address? -> We again create a new static method with specific naming. What happens when our test breaks? And how do we find out quickly which value the OrderSummary__c field has for a specific test? -> It is likely we have to dig into the factory class itself to find out. What if we need to change this value just for one of our new tests?
This is an awful state for our code. The harder it is to understand unit tests, the slower it is to update them and write new ones. This leads to poorly tested code and projects that fail to meet deadlines and requirements.
It feels like our tests drag us down and slow us down.
How can we avoid this terrible state?
In Part Two of our Builder Pattern blog series, we’ll see how the Builder Pattern can clean up some of the issues outlined above.
#blog #builderPattern #mavens
March 01, 2016
We recently updated an application for a client and helped dramatically decrease the time it takes to deploy a change. It was taking upwards to 2 weeks to get through a full deployment the application and now a change can be made and deployed in a matter of minutes.Read more
February 22, 2016
What Problem is Being Solved?
Salesforce Lightning is a great platform and one of the cool “features” is that it encourages the developers to document their Lightning components using the
tags. The platform will then dynamically build documentation specific to your org.
One minor gripe I have is needing to remember the path to the documentation. Read more
January 04, 2016
subscribe via RSS