6

I'm developing a managed package and I need to implement some test classes to test my code. However, I'm not sure how to write my tests in such a way so that they don't break due to custom rules put in place by users where my package is going to be installed. Let's take this for example:

In my test class I need to prepare some test data in order to test my code. So I wrote this statement in order to arrange it:

insert new Account(Name = 'My Test Account');

However, this can easily break in a customer's org if a customer marked a random field as required on Account object.

Next, I thought about getting around this by mocking my classes and using a Dependency Injection approach to create records only in memory, so I don't have to worry if my test code will break some validation rule when inserting into a database. However, I then have a problem with related lists (i.e. child records), as they are read-only. The below statement will return an error that Contacts field is not writable:

Account acc = new Account(Name = 'My Test Account');
acc.Contacts = new Contact[]{new Contact(LastName = 'Doe')};

Does anybody have any ideas regarding how to get around these problems? Are there any best practices when writing test classes for packages?

5

Don't worry about coding defensively against your client's configuration; they're allowed to ignore certain types of test failures. This is noted in the documentation:

If a subscriber creates a validation rule, required field, or trigger on an object referenced by your package, your test might fail if it performs DML on this object. If this object is created only for testing purposes and never at runtime, and the creation fails due to these conflicts, you might be safe to ignore the error and continue the test. Otherwise, contact the customer and determine the impact.

The most important thing is that your code does not fail unit tests during upload, including code coverage. This is the only time you need to fix your code.

  • Awesome, I didn't know about this. Thanks! – smukov May 1 '17 at 21:36
  • 1
    The only caveat is callouts. If a callout in your managed code is triggered by their local code there is no way for them to properly test it and you need to code a way to allow them to skip the callout. Supposedly they can implement your Mock implementation but I have not been successful with that to date and with the test now failing instead of just stopping it can be an issue. If someone else has I would be interested in hearing how – Eric May 1 '17 at 21:44
  • @Eric That's an interesting caveat. I know historically you'd set up HttpCalloutMock interface classes as global so they could call unit tests against them. Does that no longer work? – sfdcfox May 1 '17 at 22:08
  • @sfdcfox - In my testing with a managed package and local code Implementing the managed mock interface did not invoke the mock callout. I have not tested it in the last few months but when SF changed to failing a test for a callout without a mock it caused a lot of problems deploying a trigger that caused a package to make a callout (Opportunity). I wrote a class about a month ago that implemented a managed mock and it did not get invoked. Its supposed to work according to docs but that has not been my experience. - I'll work up an example now....Curious – Eric May 1 '17 at 22:14
  • 1
    @Eric Alright. I'll ask some people I know, maybe they can shed some light on it. – sfdcfox May 1 '17 at 23:09
3

As per @sfdcfox's answer, your managed package test cases won't run on package installation as it's near impossible to handle all the customization that could exist in any subscriber org that installs the managed package.

However, say there is something that absolutely must be tested as part of the managed package installation. In this case you can use @IsTest(OnInstall=true) to force either a single test method or an entire classes tests to run.

  • Thank you for this answer, Daniel. This will definitely be useful to me. – smukov May 1 '17 at 23:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.