I have Multiple Classes that contain code that runs only when the Org is Multi-Currency Enabled. I wouldn't prefer Activating Multiple Currencies in my Org though. Is there a way to cover that code in my test classes without Activating Multiple Currencies?
2 Answers
The only approach I can suggest is to de-couple, via refactoring, the majority of the code from the check for multi-currency enablement. For example, instead of:
void doSomething() {
Boolean multiCurrencyEnabled = Schema.getGlobalDescribe().containsKey('CurrencyType');
if (multiCurrencyEnabled) {
// Do lots of stuff here
...
// It keeps on going...
...
// That's everything
} else {
// Do lots of other stuff here
...
// OK, that's about it
}
}
Refactor so you have something like:
public void doSomething() {
Boolean multiCurrencyEnabled = Schema.getGlobalDescribe().containsKey('CurrencyType');
if (multiCurrencyEnabled) {
doSomethingWithMultiCurrency();
} else {
doSomethingWithSingleCurrency();
}
}
@TestVisible
private void doSomethingWithMultiCurrency() {
// Do lots of stuff here
...
// It keeps on going...
...
// That's everything
}
@TestVisible
private void doSomethingWithSingleCurrency() {
// Do lots of other stuff here
...
// OK, that's about it
}
You can then write tests for the private methods, and a test for the main method. The main method's coverage will be missing a single line which isn't problematic.
If this refactoring is too complex for the number of classes, you could consider lifting the test for multi-currency out into a utility like:
public class CurrencyUtils {
@TestVisible
private static Boolean isMultiCurrency = null;
public static Boolean isMultiCurrencyEnabled() {
if (isMultiCurrency == null) {
isMultiCurrency = Schema.getGlobalDescribe().containsKey('CurrencyType');
}
return isMultiCurrency;
}
}
All your classes can then use CurrencyUtils.isMultiCurrencyEnabled() to handle the detection and you can write unit tests that do:
@IsTest
static void testSomethingWithSingleCurrency() {
CurrencyUtils.isMultiCurrency = false;
// Now test without multi-currency
}
@IsTest
static void testSomethingWithMultiCurrency() {
CurrencyUtils.isMultiCurrency = true;
// Now test with multi-currency
}
Of course, in both cases you may include SOQL queries or other logic that only works when other values are available that are only available in multi-currency orgs; these would also need some abstraction to allow you to intercept and change the behaviour for your tests. This may reduce coverage, but if done well this should only reduce it by a small amount.
No. You'll only be able to cover that code by having multi-currency enabled. There's no way to fake a setting like this for a unit test.