I’m toying with the idea of adding a “unit test” custom object to apex-lang and I’d really like to know your thoughts. If possible, please read details below and leave a comment with your feedback.
My utopian vision for apex-lang is that it’s unit tests would succeed in any salesforce org capable of executing apex code. I’ve taken great care to make the unit tests as portable as possible; however, one area where this falls short is unit tests which must do DML. Those unit tests exercise the generic SObject handling methods and per the widely accepted pattern of creating data versus querying for it, they create records -> usually on Account or Contact. The problem with this approach of course, is these unit tests will fail when a required field is added to objects like Account or Contact.
Which brings me to my idea: inclusion of a custom object in apex-lang whose sole purpose is make unit tests which require SObject instances more predictable. The custom object would never be used in any practical sense other than in unit tests. I would also add as many fields as there are distinct field types; in other words, there’d be a string field, a date field, a multi-select picklist field and so on. In addition to making apex-lang unit tests more predictable, I think there’s a good use case for consumers of apex-lang who write generic SObject handling code. I do this often, like in the geocoding toolkit I created for a Cloudspokes challenge.
The first downside is I’d be violating another vision of mine for apex-lang: that it consist of apex code and apex code only. Probably not a big deal to throw in a custom object and I need to just get over it. The other downside I can think of is apex-lang would be burning a custom object. But it seems to me that most orgs have plenty to spare so that’s probably not a big deal either.
Thoughts?
Facebook
flickr
Linked In
Twitter
Seems interesting Richard ! but honestly I can’t understand how this new custom object will help fixing the required fields problem. Can you add some more sun shine on that ?
Apex-lang unit tests that reference Account or Contact would be rewritten to utilize a new custom object (call it Foo) included with apex-lang. I guess someone could still add a required field to Foo post install; however, the chances of that are much less than someone adding a required field to Account or Contact.
Hey Richard, one heuristic approach I’ve used (not ideal) as a fallback is to query the most recently created instance of the object type if the test version i created failed.
E.g.
public Account getTestAccount() {
Account testAccount = new Account(name = ‘test’);
try {
insert testAccount;
return testAccount;
} catch(Exception) {
return [select id from Account order by lastModifiedDate desc limit 1];
}
}
Another option to consider would be to use a custom setting which for most intensive purposes behave like sobjects, but can’t have validation rules defined for them.
A final option would be to choose to see if you can find a standard object that can be inserted but can’t have validation rules defined against it. Static Resources are one object that comes to mind, but I imagine there are others.
You’re custom object approach makes complete sense, although I’d worry about administrator’s accidentally breaking it as you suggest. IFIRC one of the original versions of CMSForce used a test custom object called aptly enough Test__c that was used in its test methods. However administrator’s had a tendency to delete the object (it was only referenced dynamically) blocking any future deployments (package was unmanaged).
At Dreamforce last year project management mentioned that test methods to side step validation rules and required fields were on the drawing boards but still in very earlier phases. Hopefully they’ll figure this out sooner than later although I’m not holding my breath.
Hope things are going well over at EDL. I still got a stack of cert assignments to work through if you ever get border
.