0

I am new to fflib, currently I am struggling with tests. Maybe there is someone who can help me :)

    public class someclass{
       SEL_Contact contactSel = SEL_Contact.newInstance();

       public String go(){
         Account acc = new Account();
           Id personAccId = APP_UTL_RecordType.getRecordTypeId('Account', 'PersonAccount');
          acc.FirstName = data.firstName;
          uow.registerNew(acc);
          uow.commitWork();
          System.debug('acc '+ acc.Id);
          Contact[] contacts = contactSel.selectByAccountId(new Set<Id>{acc.Id}, new List<SObjectField>{});
    return '1';
    }
    }

How can I test this? I've tried

    fflib_ApexMocks mocks = new fflib_ApexMocks();
    fflib_ISObjectUnitOfWork uowMock = new fflib_SObjectMocks.SObjectUnitOfWork(mocks);
    SEL_Contact conSel = (SEL_Contact) mocks.mock(SEL_Contact.class)
    mocks.startStubbing();
    mocks.when(conSel.sObjectType()).thenReturn(Contact.SObjectType);
    mocks.when(conSel.selectByAccountId(new Set<Id> {accId}, new List<SObjectField>{})).thenReturn(new List<Contact> {conRec});
    mocks.stopStubbing();

But i don't know how to make selector return planned contact. I guess I am missing some uow mock?

4
  • 1
    Basically you need to use some kind of dependency injection. Currently you created a mocked selector conSel. Now you need to make sure the code you're testing uses that very instance. Since you haven't posted the class you're testing it's hard to give more advises
    – nchursin
    Sep 22, 2020 at 16:34
  • I do have this dependency injected(via newinstance method), I think issue is more that what is passed to selector is not what my mock expect.... Sep 22, 2020 at 16:46
  • @ArturKępczyński in some of the implementations that I have seen, Application class takes care of the spawning an instance of a selector class. If you check an example of fflib_Application class, there are methods newInstance to spawn selector by sObject type, as well as setMock method in order to allow mocking of method returned. That might help, but will require changes in existing newInstance method of selector class itself
    – kurunve
    Sep 22, 2020 at 19:52
  • 1
    AFAIR newInstance actually instantiates a new selector instead of returning a singleton instance. So you need to inject the mock in some other way
    – nchursin
    Sep 25, 2020 at 18:44

1 Answer 1

0

This is the pattern I use when a selector and unitOfWork need mocking

// Given mocks environment
fflib_ApexMocks mocks = new fflib_ApexMocks();

// Given mockUoW
fflib_SObjectUnitOfWork mockUow = (fflib_SObjectUnitOfWork) mocks.mock(fflib_SObjectUnitOfWork.class);

// Given mock Selector
SEL_Contact mockContactsSelector = (SEL_Contact) mocks.mock(SEL_Contact.class);

// Given mockContactsSelector response
Contact[] mockContacts = new List<Contact>> {
   new Contact(...),
   new Contact(...)
};

// Given mocks response
mocks.startStubbing();
mocks.when(mockContactsSelector.sObjectType()).thenReturn(Contact.SObjectType);
mocks.when(mockContactsSelector.selectById((Set<Id>)fflib_Match.anyObject(),(SobjectField[])fflib_Match.anyObject()))
            .thenReturn(mockContacts);
mocks.stopStubbing();


// Given mocks injected
Application.UnitOfWork.setMock(mockUow);
Application.Selector.setMock(mockContactsSelector);

// When code-under test invoked
new someclass().go();

// Then verify Account registered new
((fflib_SObjectUnitOfWork)mocks.verify(mockUow,mocks.times(1).description('sb Account created')))
                    .registerNew(fflib_Match.sObjectWith(new Map<SObjectField,Object> {
                                Account.FirstName => 'xxxx'
            }));
// Then verify work committed
((fflib_SObjectUnitOfWork)mocks.verify(mockUow,mocks.times(1).description('commitwork sb called')))
                        .commitWork();

Notes

  1. I use the naming convention suggested by the Fawcett book for selectors and would use: ContactsSelector instead of SEL_Contact
  2. Note that when mocking selectors, the stubbing has to include a return value for the call .sObjectType() as I illustrate above.
  3. My ApexMocks are not Working, What Could be Wrong?

You must log in to answer this question.

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