1

I have code where in the same Unit of Work I'm inserting a record and a related record, for example an Account and Contact.

Account acc = new Account(Name = 'Test acc');
unitOfWork.registerNew(acc);

unitOfWork.registerNew(new Contact(
   LastName = 'Test contact'
), Contact.AccountId, acc);
    
unitOfWork.commitWork();

How do I now test that registerNew() was called with a correct account? I think I can do it with argument captors, but this produced a ton of hard to read code when I tried to do it. Is there any better way? For now I have created a workaround by matching that an account was passed to registerNew with correct name (fflib_Match.sObjectWithName), but I don't think that's a good test, as there may be more than one account registered with the same name (not shown in the example).

1 Answer 1

1

Since it is unit test code, you should know how many Contacts will be added to the same parent account

Thus, your ApexMocks verify for

unitOfWork.registerNew(new Contact(
                          LastName = 'Test contact'
), Contact.AccountId, acc);

will be

Integer expectedContactsPerAccount = 3;
((fflib_SObjectUnitOfWork) mocks.verify(mockUow,mocks
          .times(expectedContactsPerAccount)
          .description('should be ' + expectedContactsPerAccount + ' contacts added to Account 'testAccount')))
      .registerNew(fflib_Match.sObjectWith(new Map<SObjectField,Object> {
                                 Contact.LastName => 'Test contact'
                                 }),
                   fflib_Match.eqSObjectField(Contact.AccountId),
                   fflib_Match.sObjectWith(new Map<SObjectField,Object> {
                Account.Name => 'Test acc'
            }));

Now, if your code under test could create two Accounts with the same Account.Name and there is no other distinguishing field between the two Accounts, I'd suggest redesigning your application as creating multiple Accounts with the same Name doesn't seem like good design.

I don't see how ArgumentCaptors will help as acc.Id is local to the code under test and you won't have that unless the method returns the inserted Accounts so you can then in turn verify the second registerNew

Another approach would be to move the account creation into a different service class and use Apex Mocks answers to return a mocked Account (including Account.Id). Then, you could verify the second registerNew of Contacts against the Apex Mocks Answers of the simulated inserted Accounts. See Answering with ApexMocks

But frankly, when faced with your situation, I'd design my unit test to avoid creating Accounts with duplicate names (and no other disambiguation) so I could reliably verify the registerNew for Contact.

You must log in to answer this question.

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