I am hoping for some help in figuring out why some mocking is not working. I am currently using ApexMocks and the FinancialForce Apex Common Library and knowledge of those would be necessary to help answer the question.
I have currently setup a domain class for the Account_Health__c object which has a MD relationship with Account.
The method setAccountHighlightedFields is called onAfterInsert and onAfterUpdate:
public void setAccountHighlightedFields(Map<Id, SObject> oldRecords, fflib_ISObjectUnitOfWork uow)
{
Set<Id> accountIds = new Set<id>();
List<Account_Health__c> ahChanged = new List<Account_Health__c>();
if(oldRecords != NULL)
{
for(Account_Health__c ah : (List<Account_Health__c>) records)
{
if(oldRecords.containsKey(ah.id))
{
Account_Health__c oldAH = (Account_Health__c) oldRecords.get(ah.Id);
if(oldAH.Strategic_Account__c != ah.Strategic_Account__c || oldAH.Escalated_Account__c != ah.Escalated_Account__c || oldAH.Strategic_Objective__c != ah.Strategic_Objective__c || oldAH.Reference_Account__c != ah.Reference_Account__c)
{
accountIds.add(ah.Account__c);
ahChanged.add(ah);
}
}
}
}
else
{
for(Account_Health__c ah : (List<Account_Health__c>) records)
{
if(ah.Strategic_Account__c || ah.Escalated_Account__c || ah.Strategic_Objective__c == 'Trial Support' || ah.Reference_Account__c != NULL)
{
accountIds.add(ah.Account__c);
ahChanged.add(ah);
}
}
}
if(accountIds.size() > 0)
{
Map<Id, Account> accountMap = new Map<Id, Account>(AccountsSelector.newInstance().selectById(accountIds));
for(Account_Health__c ah : ahChanged)
{
Account acc = accountMap.get(ah.Account__c);
if(acc.Reference_Account__c != ah.Reference_Account__c)
{
acc.Reference_Account__c = ah.Reference_Account__c;
}
if(acc.Strategic_Account__c != ah.Strategic_Account__c)
{
acc.Strategic_Account__c = ah.Strategic_Account__c;
}
if(acc.Escalated_Account__c != ah.Escalated_Account__c)
{
acc.Escalated_Account__c = ah.Escalated_Account__c;
}
if(acc.Trial_Account__c && ah.Strategic_Objective__c != 'Trial Support')
{
acc.Trial_Account__c = FALSE;
}
else if(!acc.Trial_Account__c && ah.Strategic_Objective__c == 'Trial Support')
{
acc.Trial_Account__c = TRUE;
}
uow.registerDirty(acc);
}
}
}
I have been writting a mock method to test the update portion of the method. I have a mock class created and setup both the new data and the old data. Prior to creating a new instance of the domain, the old and new values are correct. After I create the instance of the domain and call the method, within the class the Records list is the same as the oldRecords map values. Can anyone identify why this occurring?
@isTest
private static void testsetAccountHighlightedFieldsMock()
{
fflib_ApexMocks mocks = new fflib_ApexMocks();
fflib_ISObjectUnitOfWork uowMock = new fflib_SObjectMocks.SObjectUnitOfWork(mocks);
IAccountsSelector accSelectorMock = new Mocks.AccountsSelector(mocks);
IAccountHealth domainMock = new Mocks.AccountHealth(mocks);
List<Account> accounts = TestingUtilsMock.createAccounts(1);
Map<Id, SObject> oldAccountHealths = new Map<Id, SObject>();
for(Account acc : accounts)
{
oldAccountHealths.putAll(TestingUtilsMock.createAccountHealths(1, acc.Id));
}
Map<Id, SObject> newAccountHealths = oldAccountHealths.deepClone();
for(Account_Health__c ah : (List<Account_Health__c>)newAccountHealths.values())
{
ah.Escalated_Account__c = TRUE;
ah.Strategic_Account__c = TRUE;
ah.Strategic_Objective__c = 'Trial Support';
ah.Reference_Account__c = 'Yes';
}
mocks.startStubbing();
mocks.when(domainMock.sObjectType()).thenReturn(Account_Health__c.SObjectType);
mocks.when(accSelectorMock.sObjectType()).thenReturn(Account.SObjectType);
mocks.when(accSelectorMock.selectById(new Map<Id,SObject>(accounts).keySet())).thenReturn(accounts);
mocks.stopStubbing();
Application.UnitOfWork.setMock(uowMock);
Application.Domain.setMock(domainMock);
Application.Selector.setMock(accSelectorMock);
IAccountHealth accountHealthInstance = AccountHealth.newInstance((List<Account_Health__c>)newAccountHealths.values());
accountHealthInstance.setAccountHighlightedFields(oldAccountHealths, uowMock);
for(Account acc : accounts)
{
system.assert(acc.Strategic_Account__c, 'Account should now be set as strategic');
system.assert(acc.Escalated_Account__c, 'Account should now be escalated');
system.assert(acc.Trial_Account__c, 'Account should now be set to trial');
system.assertEquals('Yes', acc.Reference_Account__c, 'Account should have been set as a reference account');
}
}
Here is my mock method that is using the ApexMock Framework (contained in Mocks.cls):
public class AccountHealth extends fflib_SObjectMocks.SObjectDomain implements IAccountHealth
{
private fflib_ApexMocks mocks;
public AccountHealth(fflib_ApexMocks mocks)
{
super(mocks);
this.mocks = mocks;
}
public void setAccountHighlightedFields(Map<Id, SObject> oldRecords, fflib_ISObjectUnitOfWork uow)
{
mocks.mockVoidMethod(this, 'setAccountHighlightedFields', new List<Object> {oldRecords, uow});
}
}
If needed, here are the TestingUtilsMock methods:
public static List<Account> createAccounts(Integer size)
{
List<Account> accounts = new List<Account>();
for(Integer i = 0; i < size; i++)
{
Account test = new Account(
Id = fflib_IDGenerator.generate(Account.SObjectType),
Name = 'An Account ' + i,
BillingStreet = '220 5TH AVE',
BillingState = 'NY',
BillingCountry = 'United States',
Status__c = 'Prospect',
Sector_new__c = 'Unknown',
Strategic_Account__c = FALSE,
Escalated_Account__c = FALSE,
Trial_Account__c = FALSE,
Reference_Account__c = ''
);
accounts.add (test);
}
return accounts;
}
public static List<Account_Health__c> createAccountHealths(Integer size, Id accountId)
{
List<Account_Health__c> accountHealths = new List<Account_Health__c>();
for(Integer i = 0; i < size; i++)
{
Account_Health__c ah = new Account_Health__c(
Id = fflib_IDGenerator.generate(Account_Health__c.SObjectType),
Account__c = accountId,
Escalated_Account__c = FALSE,
Strategic_Account__c = FALSE,
Strategic_Objective__c = ''
);
accountHealths.add(ah);
}
return accountHealths;
}