9

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;
}
3
  • 1
    Who is making the callout that you are attempting to Mock, you or FF. If it is FF then you will have to use their mock classes as it will not use yours.
    – Eric
    Commented Nov 25, 2015 at 18:58
  • I am mocking my own class/method using the FF ApexMocks and Apex Common libraries. I'll update the post with the Mocks method for the domain class. Commented Nov 25, 2015 at 19:10
  • Updated the question with the Mock class/method. Commented Nov 25, 2015 at 19:12

1 Answer 1

1

It appears as though in fflib_Application.newInstance(List records) you need to provide a concrete list of records. I had assumed that (List)newAccountHealths.values() was the same as passing in a concrete list which appears to not be the case. I ended up passing a List in my test class when creating an instance of my domain class and everything worked as expected.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .