I need to setup test data in proprietary cloud platform (Salesforce.com) where I have no access to advanced testing frameworks. Besides that you can read my code example like it would be Java.
Setting up data basically means to insert records of a quite complex object structure into the database. I decided to go with the Test Data Builder pattern described in this blog post and the related book.
It took me a while to realize that this makes everything much harder as you have to decide where to put your actual DML (meaning when do you insert the record you build).
If you do it naively in the build()
I see no way to optimize / bulkify DML statements - which would be very important at the Salesforce.com platform.
On the other hand if you pass around Builder instances instead of Record instances around and build everything in the end you need extra methods to pass (in-memory but no yet persisted records) around.
@isTest
public class OpportunityBuilder {
private Account parentAccount
public Opportunity record;
private List<LineItemBuilder> lineItemBuilders;
public OpportunityBuilder(Account acc) {
record = new Opportunity();
record.Name = ...
record.Account = acc.Id;
...
lineItemBuilders = new List<LineItemBuilder>();
}
public OpportunityBuilder add(LineItemBuilder lib) {
lineItemBuilders.add( lib );
return this;
}
public Opportunity build() {
insert record;
List<LineItem> lis = new List<LineItem>();
for(LineItemBuilder builder : lineItemBuilders) {
LineItem li = builder.record;
li.Opportunity = record.Id; // Id requires previous DML
lis.add(li);
}
insert lis;
return record;
}
}
My question now is:
- How can I make my Builder classes super-extensible? Delay DML and pass Builders instead of records?
- Do you know of any resource which enhances the above pattern for database use?
- What other solutions do you know that would be an alternative?