From 24b46dccac7d330108b951b1c9d440c25c94767c Mon Sep 17 00:00:00 2001 From: "John M. Daniel" <imjohnmdaniel@ce-v.com> Date: Sun, 8 May 2022 17:00:37 -0400 Subject: [PATCH] Check in of related to an attempt to remove the dependency on fflib_SObjectMocks class In the end, this attempt is not feasible because relying on "inner class implementations of interfaces" fails with a `System.TypeException` where `Test.createStub()` cannot be called with inner Apex classes --- .../main/classes/fflib_Application.cls | 60 +--- .../test/classes/fflib_ApplicationTest.cls | 290 +++++++++++------- .../test/classes/mocks/fflib_SObjectMocks.cls | 237 -------------- .../mocks/fflib_SObjectMocks.cls-meta.xml | 5 - 4 files changed, 201 insertions(+), 391 deletions(-) delete mode 100644 sfdx-source/apex-common/test/classes/mocks/fflib_SObjectMocks.cls delete mode 100644 sfdx-source/apex-common/test/classes/mocks/fflib_SObjectMocks.cls-meta.xml diff --git a/sfdx-source/apex-common/main/classes/fflib_Application.cls b/sfdx-source/apex-common/main/classes/fflib_Application.cls index 889c8163320..8a0c9bfedcb 100644 --- a/sfdx-source/apex-common/main/classes/fflib_Application.cls +++ b/sfdx-source/apex-common/main/classes/fflib_Application.cls @@ -39,11 +39,6 @@ public virtual class fflib_Application protected List<SObjectType> m_objectTypes; protected fflib_ISObjectUnitOfWork m_mockUow; - /** - * Constructs a Unit Of Work factory - **/ - public UnitOfWorkFactory() { } - /** * Constructs a Unit Of Work factory * @@ -61,10 +56,7 @@ public virtual class fflib_Application **/ public virtual fflib_ISObjectUnitOfWork newInstance() { - // Mock? - if(m_mockUow!=null) - return m_mockUow; - return new fflib_SObjectUnitOfWork(m_objectTypes); + return m_mockUow!=null ? m_mockUow : new fflib_SObjectUnitOfWork(m_objectTypes); } /** @@ -74,10 +66,7 @@ public virtual class fflib_Application **/ public virtual fflib_ISObjectUnitOfWork newInstance(fflib_SObjectUnitOfWork.IDML dml) { - // Mock? - if(m_mockUow!=null) - return m_mockUow; - return new fflib_SObjectUnitOfWork(m_objectTypes, dml); + return m_mockUow!=null ? m_mockUow : new fflib_SObjectUnitOfWork(m_objectTypes, dml); } /** @@ -90,10 +79,7 @@ public virtual class fflib_Application **/ public virtual fflib_ISObjectUnitOfWork newInstance(List<SObjectType> objectTypes) { - // Mock? - if(m_mockUow!=null) - return m_mockUow; - return new fflib_SObjectUnitOfWork(objectTypes); + return m_mockUow!=null ? m_mockUow : new fflib_SObjectUnitOfWork(objectTypes); } /** @@ -106,10 +92,7 @@ public virtual class fflib_Application **/ public virtual fflib_ISObjectUnitOfWork newInstance(List<SObjectType> objectTypes, fflib_SObjectUnitOfWork.IDML dml) { - // Mock? - if(m_mockUow!=null) - return m_mockUow; - return new fflib_SObjectUnitOfWork(objectTypes, dml); + return m_mockUow!=null ? m_mockUow : new fflib_SObjectUnitOfWork(objectTypes, dml); } @TestVisible @@ -128,11 +111,6 @@ public virtual class fflib_Application protected Map<Type, Object> m_serviceInterfaceTypeByMockService; - /** - * Constructs a simple Service Factory - **/ - public ServiceFactory() { } - /** * Constructs a simple Service Factory, * using a Map of Apex Interfaces to Apex Classes implementing the interface @@ -183,11 +161,6 @@ public virtual class fflib_Application protected Map<SObjectType, Type> m_sObjectBySelectorType; protected Map<SObjectType, fflib_ISObjectSelector> m_sObjectByMockSelector; - /** - * Constructs a simple Selector Factory - **/ - public SelectorFactory() { } - /** * Consturcts a Selector Factory linking SObjectType's with Apex Classes implement the fflib_ISObjectSelector interface * Note that the factory does not check the given Apex Classes implement the interface @@ -215,7 +188,7 @@ public virtual class fflib_Application // Determine Apex class for Selector class Type selectorClass = m_sObjectBySelectorType.get(sObjectType); - if(selectorClass==null) + if( selectorClass == null ) throw new DeveloperException('Selector class not found for SObjectType ' + sObjectType); // Construct Selector class and query by Id for the records @@ -288,11 +261,6 @@ public virtual class fflib_Application protected Map<Object, fflib_IDomain> mockDomainByObject; - /** - * Constructs a Domain factory - **/ - public DomainFactory() { } - /** * Constructs a Domain factory, using an instance of the Selector Factory * and a map of Apex classes implementing fflib_ISObjectDomain by SObjectType @@ -412,16 +380,20 @@ public virtual class fflib_Application ); } - @TestVisible - protected virtual void setMock(fflib_ISObjectDomain mockDomain) - { - mockDomainByObject.put((Object) mockDomain.sObjectType(), (fflib_IDomain) mockDomain); - } - @TestVisible protected virtual void setMock(fflib_IDomain mockDomain) { - mockDomainByObject.put(mockDomain.getType(), mockDomain); + if ( mockDomain != null ) + { + if ( mockDomain instanceof fflib_ISObjectDomain ) + { + mockDomainByObject.put(((fflib_ISObjectDomain) mockDomain).sObjectType(), (fflib_IDomain) mockDomain); + } + else + { + mockDomainByObject.put(mockDomain.getType(), mockDomain); + } + } } protected virtual Map<Object, Type> getConstructorTypeByObject(Map<SObjectType, Type> constructorTypeBySObjectType) diff --git a/sfdx-source/apex-common/test/classes/fflib_ApplicationTest.cls b/sfdx-source/apex-common/test/classes/fflib_ApplicationTest.cls index af1dd15274f..fc33bb74438 100644 --- a/sfdx-source/apex-common/test/classes/fflib_ApplicationTest.cls +++ b/sfdx-source/apex-common/test/classes/fflib_ApplicationTest.cls @@ -22,8 +22,7 @@ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**/ - + */ @IsTest private class fflib_ApplicationTest { @@ -33,72 +32,73 @@ private class fflib_ApplicationTest // Registered Accounts domain class by SObject List Id testAccountId = fflib_IDGenerator.generate(Account.SObjectType); fflib_IDomain domainObjectAcct = - Domain.newInstance( + TestDomainFactory.newInstance( new List<Account> { new Account( Id = testAccountId, Name = 'Test Account') }); - System.assert(domainObjectAcct instanceof AccountsDomain); + System.assert(domainObjectAcct instanceof Accounts); System.assertEquals(testAccountId, getFirstSObject(domainObjectAcct).Id); // Registered Accounts domain class by SObject List testAccountId = fflib_IDGenerator.generate(Account.SObjectType); domainObjectAcct = - Domain.newInstance( + TestDomainFactory.newInstance( new List<SObject> { new Account( Id = testAccountId, Name = 'Test Account') } , Account.SObjectType); - System.assert(domainObjectAcct instanceof AccountsDomain); + System.assert(domainObjectAcct instanceof Accounts); System.assertEquals(testAccountId, getFirstSObject(domainObjectAcct).Id); // Registered Opportunities domain class by SObject List Id testOpportunityId = fflib_IDGenerator.generate(Opportunity.SObjectType); fflib_IDomain domainObjectOpp = - Domain.newInstance( + TestDomainFactory.newInstance( new List<Opportunity> { new Opportunity( Id = testOpportunityId, Name = 'Test Opportunity') }); System.assertEquals(testOpportunityId, getFirstSObject(domainObjectOpp).Id); - System.assert(domainObjectOpp instanceof OpportuntiesDomain); + System.assert(domainObjectOpp instanceof Opportunties); // Test failure for creating new instance using IConstructable2 // for domain class that does not support it testOpportunityId = fflib_IDGenerator.generate(Opportunity.SObjectType); domainObjectOpp = - Domain.newInstance( + TestDomainFactory.newInstance( new List<SObject> { new Opportunity( Id = testOpportunityId, Name = 'Test Opportunity') } , Opportunity.SObjectType); System.assertEquals(testOpportunityId, getFirstSObject(domainObjectOpp).Id); - System.assert(domainObjectOpp instanceof OpportuntiesDomain); + System.assert(domainObjectOpp instanceof Opportunties); // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); mocks.startStubbing(); - fflib_ISObjectDomain domainMock = new fflib_SObjectMocks.SObjectDomain(mocks); - mocks.when(domainMock.sObjectType()).thenReturn(Account.SObjectType); + // fflib_ISObjectDomain domainMock = new fflib_SObjectMocks.SObjectDomain(mocks); + fflib_ApplicationTest.IAccounts accountsDomainMock = (fflib_ApplicationTest.IAccounts)mocks.mock(fflib_ApplicationTest.IAccounts.class); + mocks.when(accountsDomainMock.sObjectType()).thenReturn(Account.SObjectType); mocks.stopStubbing(); - Domain.setMock(domainMock); + TestDomainFactory.setMock(accountsDomainMock); // When domainObjectAcct = - Domain.newInstance( + TestDomainFactory.newInstance( new List<Account> { new Account( Id = testAccountId, Name = 'Test Account') }); // Then - System.assert(domainObjectAcct instanceof fflib_SObjectMocks.SObjectDomain); + System.assert(domainObjectAcct instanceof IAccounts); // When domainObjectAcct = - Domain.newInstance( + TestDomainFactory.newInstance( new List<SObject> { new Account( Id = testAccountId, @@ -106,7 +106,7 @@ private class fflib_ApplicationTest , Account.SObjectType); // Then - System.assert(domainObjectAcct instanceof fflib_SObjectMocks.SObjectDomain); + System.assert(domainObjectAcct instanceof IAccounts); } private static SObject getFirstSObject(fflib_IDomain domainObjectAcct) @@ -119,8 +119,8 @@ private class fflib_ApplicationTest { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); - mocks.startStubbing(); - fflib_ISObjectSelector selectorMock = new fflib_SObjectMocks.SObjectSelector(mocks); + IAccountsSelector mockAccountsSelector = (IAccountsSelector)mocks.mock(IAccountsSelector.class); + Id testAccountId = fflib_IDGenerator.generate(Account.SObjectType); List<Account> accounts = new List<Account> @@ -128,17 +128,18 @@ private class fflib_ApplicationTest Id = testAccountId, Name = 'Test Account') }; Set<Id> accountIds = new Map<Id, Account>(accounts).keySet(); - mocks.when(selectorMock.selectSObjectsById(accountIds)).thenReturn(accounts); - mocks.when(selectorMock.sObjectType()).thenReturn(Account.SObjectType); + mocks.startStubbing(); + mocks.when(mockAccountsSelector.selectSObjectsById(accountIds)).thenReturn(accounts); + mocks.when(mockAccountsSelector.sObjectType()).thenReturn(Account.SObjectType); mocks.stopStubbing(); // When - Selector.setMock(selectorMock); - fflib_IDomain domainObjectAcc = Domain.newInstance(new Set<Id> { testAccountId }); + TestSelectorFactory.setMock(mockAccountsSelector); + fflib_IDomain domainObjectAcc = TestDomainFactory.newInstance(new Set<Id> { testAccountId }); // Then List<Account> assertAccounts = (List<Account>) domainObjectAcc.getObjects(); - System.assert(domainObjectAcc instanceof AccountsDomain); + System.assert(domainObjectAcc instanceof Accounts); System.assertEquals(testAccountId, getFirstSObject(domainObjectAcc).Id); System.assertEquals(1, assertAccounts.size()); System.assertEquals(testAccountId, assertAccounts[0].Id); @@ -149,7 +150,7 @@ private class fflib_ApplicationTest private static void callingDomainFactoryWithGenericListShouldGiveException() { try { - Domain.newInstance(new List<SObject>()); + TestDomainFactory.newInstance(new List<SObject>()); System.assert(false, 'Expected exception'); } catch (fflib_Application.DeveloperException e) { System.assertEquals('Unable to determine SObjectType', e.getMessage()); @@ -160,7 +161,7 @@ private class fflib_ApplicationTest private static void callingDomainFactoryWithNoSObjectTypeShouldGiveException() { try { - Domain.newInstance(new List<SObject>(), null); + TestDomainFactory.newInstance(new List<SObject>(), null); System.assert(false, 'Expected exception'); } catch (fflib_Application.DeveloperException e) { System.assertEquals('Must specify sObjectType', e.getMessage()); @@ -171,14 +172,14 @@ private class fflib_ApplicationTest private static void callingDomainFactoryWithInAccessableConstructorShouldGiveException() { try { - Domain.newInstance(new List<Product2>{ new Product2(Name = 'Test Product') }); + TestDomainFactory.newInstance(new List<Product2>{ new Product2(Name = 'Test Product') }); System.assert(false, 'Expected exception'); } catch (fflib_Application.DeveloperException e) { System.assertEquals('Domain constructor class not found for SObjectType Product2', e.getMessage()); } try { - Domain.newInstance(new List<SObject>{ new Product2(Name = 'Test Product') }, Product2.SObjectType); + TestDomainFactory.newInstance(new List<SObject>{ new Product2(Name = 'Test Product') }, Product2.SObjectType); System.assert(false, 'Expected exception'); } catch (fflib_Application.DeveloperException e) { System.assertEquals('Domain constructor class not found for SObjectType Product2', e.getMessage()); @@ -189,7 +190,7 @@ private class fflib_ApplicationTest private static void callingDomainFactoryWithContructorClassThatDoesNotSupportIConstructableShouldGiveException() { try { - Domain.newInstance(new List<Contact>{ new Contact(LastName = 'TestContactLName') }); + TestDomainFactory.newInstance(new List<Contact>{ new Contact(LastName = 'TestContactLName') }); System.assert(false, 'Expected exception'); } catch (System.TypeException e) { @@ -198,7 +199,7 @@ private class fflib_ApplicationTest } try { - Domain.newInstance(new List<SObject>{ new Contact(LastName = 'TestContactLName') }, Contact.SObjectType); + TestDomainFactory.newInstance(new List<SObject>{ new Contact(LastName = 'TestContactLName') }, Contact.SObjectType); System.assert(false, 'Expected exception'); } catch (System.TypeException e) { System.assert(Pattern.Matches('Invalid conversion from runtime type \\w*\\.?fflib_ApplicationTest\\.ContactsConstructor to \\w*\\.?fflib_IDomainConstructor', @@ -210,11 +211,12 @@ private class fflib_ApplicationTest private static void callingUnitOfWorkFactoryShouldGivenStandardImplsAndMockImpls() { // Standard behaviour - System.assert(UnitOfWork.newInstance() instanceof fflib_SObjectUnitOfWork); + System.assert(TestUnitOfWorkFactory.newInstance() instanceof fflib_SObjectUnitOfWork); // Mocking behaviour - UnitOfWork.setMock(new fflib_SObjectMocks.SObjectUnitOfWork(new fflib_ApexMocks())); - System.assert(UnitOfWork.newInstance() instanceof fflib_SObjectMocks.SObjectUnitOfWork); + fflib_ApexMocks mocks = new fflib_ApexMocks(); + fflib_ISObjectUnitOfWork mockUow = (fflib_ISObjectUnitOfWork)mocks.mock(fflib_ISObjectUnitOfWork.class); + TestUnitOfWorkFactory.setMock(mockUow); } @IsTest @@ -222,62 +224,73 @@ private class fflib_ApplicationTest { // Standard behaviour System.assert( - UnitOfWork.newInstance( + TestUnitOfWorkFactory.newInstance( new List<SObjectType>{ Account.SObjectType} ) instanceof fflib_SObjectUnitOfWork); - // Mocking behaviour - UnitOfWork.setMock(new fflib_SObjectMocks.SObjectUnitOfWork(new fflib_ApexMocks())); - System.assert( - UnitOfWork.newInstance( - new List<SObjectType>{ Account.SObjectType} - ) instanceof fflib_SObjectMocks.SObjectUnitOfWork); } @IsTest - private static void callingServiceFactoryShouldGiveRegisteredImplsAndMockImpls() + private static void callingServiceFactoryShouldGiveRegisteredImplsImpl() { // Standard behaviour - System.assert(Service.newInstance(IAccountService.class) instanceof AccountsServiceImpl); - System.assert(Service.newInstance(IOpportunitiesService.class) instanceof OpportunitiesServiceImpl); + System.assert(TestServiceFactory.newInstance(IAccountsService.class) instanceof AccountsServiceImpl); + System.assert(TestServiceFactory.newInstance(IOpportunitiesService.class) instanceof OpportunitiesServiceImpl); try { - Service.newInstance(IContactService.class); + TestServiceFactory.newInstance(IContactService.class); System.assert(false, 'Expected exception'); } catch (fflib_Application.DeveloperException e) { System.assertEquals('No implementation registered for service interface ' + IContactService.class.getName(), e.getMessage()); } + } - // Mocking behaviour - Service.setMock(IAccountService.class, new AccountsServiceMock()); - System.assert(Service.newInstance(IOpportunitiesService.class) instanceof OpportunitiesServiceImpl); - System.assert(Service.newInstance(IAccountService.class) instanceof AccountsServiceMock); + @IsTest + private static void callingServiceFactoryWhenMockInstanceSetShouldGiveRegisteredMockImpl() + { + // Mocking behaviour + fflib_ApexMocks mocks = new fflib_ApexMocks(); + IAccountsService mockAccountsService = (IAccountsService)mocks.mock(IAccountsService.class); + TestServiceFactory.setMock(IAccountsService.class, mockAccountsService); + System.assert(TestServiceFactory.newInstance(IAccountsService.class) instanceof IAccountsService ); } @IsTest private static void callingSelectorFactoryShouldGiveRegisteredImpls() { // Standard behaviour - System.assert(Selector.newInstance(Account.SObjectType) instanceof AccountsSelector); - System.assert(Selector.newInstance(Opportunity.SObjectType) instanceof OpportuntiesSelector); + System.assert(TestSelectorFactory.newInstance(Account.SObjectType) instanceof AccountsSelector); + System.assert(TestSelectorFactory.newInstance(Opportunity.SObjectType) instanceof OpportuntiesSelector); try { - Selector.newInstance(User.SObjectType); + TestSelectorFactory.newInstance(User.SObjectType); System.assert(false, 'Expected exception'); } catch (fflib_Application.DeveloperException e) { - System.assertEquals('Selector class not found for SObjectType User', e.getMessage()); + System.assertEquals('TestSelectorFactory class not found for SObjectType User', e.getMessage()); } + + // Mock behaviour + fflib_ApexMocks mocks = new fflib_ApexMocks(); + IAccountsSelector mockAccountsSelector = (IAccountsSelector)mocks.mock(IAccountsSelector.class); + + mocks.startStubbing(); + mocks.when(mockAccountsSelector.sObjectType()).thenReturn(Account.SObjectType); + mocks.stopStubbing(); + + TestSelectorFactory.setMock( mockAccountsSelector ); + + System.assert(TestSelectorFactory.newInstance(Account.SObjectType) instanceof IAccountsSelector); } @IsTest private static void callingSelectorFactorySelectByIdWithEmptyListShouldGiveException() { try { - Selector.selectById(null); + TestSelectorFactory.selectById(null); System.assert(false, 'Expected exception'); } catch (fflib_Application.DeveloperException e) { System.assertEquals('Invalid record Id\'s set', e.getMessage()); } try { - Selector.selectById(new Set<Id>()); + TestSelectorFactory.selectById(new Set<Id>()); System.assert(false, 'Expected exception'); } catch (fflib_Application.DeveloperException e) { System.assertEquals('Invalid record Id\'s set', e.getMessage()); @@ -288,7 +301,7 @@ private class fflib_ApplicationTest private static void callingSelectorFactorySelectByIdWithMixedIdTypeListShouldGiveException() { try { - Selector.selectById( + TestSelectorFactory.selectById( new Set<Id> { fflib_IDGenerator.generate(Opportunity.SObjectType), fflib_IDGenerator.generate(Account.SObjectType) }); @@ -298,13 +311,44 @@ private class fflib_ApplicationTest } } + @IsTest + private static void callingSelectorFactorySelectByIdWithIdSetShouldSucceedWithNoRecords() + { + // Standard behaviour + try { + List<Account> testRecords = (List<Account>) TestSelectorFactory.selectById( + new Set<Id> { + fflib_IDGenerator.generate(Account.SObjectType), + fflib_IDGenerator.generate(Account.SObjectType) }); + System.assert(true, 'Expected exception'); + } catch (fflib_Application.DeveloperException e) { + System.assert(false, 'Should not throw a fflib_Application.DeveloperException'); + } catch (Exception e) { + System.assert(false, 'Should not throw a Exception'); + } + + // Mock behaviour + fflib_ApexMocks mocks = new fflib_ApexMocks(); + IAccountsSelector mockAccountsSelector = (IAccountsSelector)mocks.mock(IAccountsSelector.class); + Set<Id> testAccountIdSet = new Set<Id>(); + testAccountIdSet.add( fflib_IDGenerator.generate(Account.SObjectType) ); + testAccountIdSet.add( fflib_IDGenerator.generate(Account.SObjectType) ); + mocks.startStubbing(); + mocks.when(mockAccountsSelector.sObjectType()).thenReturn(Account.SObjectType); + mocks.stopStubbing(); + + TestSelectorFactory.setMock( mockAccountsSelector ); + + TestSelectorFactory.newInstance(Account.SObjectType); + + } @IsTest private static void callingSelectoryFactorySelectByIdShouldReturnResults() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); - mocks.startStubbing(); - fflib_ISObjectSelector selectorMock = new fflib_SObjectMocks.SObjectSelector(mocks); + IAccountsSelector mockAccountsSelector = (IAccountsSelector)mocks.mock(IAccountsSelector.class); + Id testAccountId = fflib_IDGenerator.generate(Account.SObjectType); List<Account> accounts = new List<Account> @@ -312,30 +356,32 @@ private class fflib_ApplicationTest Id = testAccountId, Name = 'Test Account') }; Set<Id> accountIds = new Map<Id, Account>(accounts).keySet(); - mocks.when(selectorMock.selectSObjectsById(accountIds)).thenReturn(accounts); - mocks.when(selectorMock.sObjectType()).thenReturn(Account.SObjectType); + + mocks.startStubbing(); + mocks.when(mockAccountsSelector.selectSObjectsById(accountIds)).thenReturn(accounts); + mocks.when(mockAccountsSelector.sObjectType()).thenReturn(Account.SObjectType); mocks.stopStubbing(); + TestSelectorFactory.setMock(mockAccountsSelector); + // When - Selector.setMock(selectorMock); - List<Account> assertAccounts = Selector.selectById(accountIds); + List<Account> assertAccounts = TestSelectorFactory.selectById(accountIds); // Then - System.assert(Selector.newInstance(Account.SObjectType) instanceof fflib_SObjectMocks.SObjectSelector); + System.assert(TestSelectorFactory.newInstance(Account.SObjectType) instanceof IAccountsSelector); System.assertEquals(1, assertAccounts.size()); System.assertEquals(testAccountId, assertAccounts[0].Id); System.assertEquals('Test Account', assertAccounts[0].Name); - System.assert(Selector.newInstance(Opportunity.SObjectType) instanceof OpportuntiesSelector); + System.assert(TestSelectorFactory.newInstance(Opportunity.SObjectType) instanceof OpportuntiesSelector); } - @IsTest - private static void callingSelectoryFactorySselectByRelationshipPassRelatedIds() + private static void callingSelectoryFactorySelectByRelationshipPassRelatedIds() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); - mocks.startStubbing(); - fflib_ISObjectSelector selectorMock = new fflib_SObjectMocks.SObjectSelector(mocks); + IAccountsSelector mockAccountsSelector = (IAccountsSelector)mocks.mock(IAccountsSelector.class); + Id testAccountId = fflib_IDGenerator.generate(Account.SObjectType); Id testOpportunityId = fflib_IDGenerator.generate(Opportunity.SObjectType); List<Account> accounts = @@ -344,10 +390,13 @@ private class fflib_ApplicationTest Id = testAccountId, Name = 'Test Account') }; Set<Id> accountIds = new Map<Id, Account>(accounts).keySet(); - mocks.when(selectorMock.selectSObjectsById(accountIds)).thenReturn(accounts); - mocks.when(selectorMock.sObjectType()).thenReturn(Account.SObjectType); + + mocks.startStubbing(); + mocks.when(mockAccountsSelector.selectSObjectsById(accountIds)).thenReturn(accounts); + mocks.when(mockAccountsSelector.sObjectType()).thenReturn(Account.SObjectType); mocks.stopStubbing(); - Selector.setMock(selectorMock); + + TestSelectorFactory.setMock(mockAccountsSelector); // When List<Opportunity> opportunties = @@ -360,26 +409,29 @@ private class fflib_ApplicationTest new Opportunity( Id = testOpportunityId, Name = 'Test Opportunity 2') }; - List<Account> assertAccounts = Selector.selectByRelationship(opportunties, Opportunity.AccountId); + List<Account> assertAccounts = TestSelectorFactory.selectByRelationship(opportunties, Opportunity.AccountId); // Then - System.assert(Selector.newInstance(Account.SObjectType) instanceof fflib_SObjectMocks.SObjectSelector); + System.assert(TestSelectorFactory.newInstance(Account.SObjectType) instanceof IAccountsSelector); System.assertEquals(1, assertAccounts.size()); System.assertEquals(testAccountId, assertAccounts[0].Id); System.assertEquals('Test Account', assertAccounts[0].Name); - System.assert(Selector.newInstance(Opportunity.SObjectType) instanceof OpportuntiesSelector); + System.assert(TestSelectorFactory.newInstance(Opportunity.SObjectType) instanceof OpportuntiesSelector); } - @IsTest private static void callingUnitOfWorkWithCustomDML() { + fflib_ApexMocks mocks = new fflib_ApexMocks(); + fflib_ISObjectUnitOfWork mockUow = (fflib_ISObjectUnitOfWork)mocks.mock(fflib_ISObjectUnitOfWork.class); + TestUnitOfWorkFactory.setMock(mockUow); + // Given a custom DML class and a new record CustomDML customDML = new CustomDML(); Account myAccount = new Account(Name = 'Test Account'); // When the unit of work is instantiated from the Application Class and the record is registered and commited - fflib_ISObjectUnitOfWork unitOfWork = UnitOfWork.newInstance(customDML); + fflib_ISObjectUnitOfWork unitOfWork = TestUnitOfWorkFactory.newInstance(customDML); unitOfWork.registerNew(myAccount); unitOfWork.commitWork(); @@ -390,13 +442,16 @@ private class fflib_ApplicationTest @IsTest private static void callingMockedUnitOfWorkWithCustomDML() { + fflib_ApexMocks mocks = new fflib_ApexMocks(); + fflib_ISObjectUnitOfWork mockUow = (fflib_ISObjectUnitOfWork)mocks.mock(fflib_ISObjectUnitOfWork.class); + TestUnitOfWorkFactory.setMock(mockUow); + // Given a custom DML class and a new record CustomDML customDML = new CustomDML(); Account myAccount = new Account(Name = 'Test Account'); // When the unit of work is instantiated from the Application Class and the record is registered and commited - UnitOfWork.setMock(new fflib_SObjectMocks.SObjectUnitOfWork(new fflib_ApexMocks())); - fflib_ISObjectUnitOfWork uow = UnitOfWork.newInstance(customDML); + fflib_ISObjectUnitOfWork uow = TestUnitOfWorkFactory.newInstance(customDML); uow.registerNew(myAccount); uow.commitWork(); @@ -408,12 +463,16 @@ private class fflib_ApplicationTest @IsTest private static void callingUnitOfWorkWithCustomObjectTypesAndDML() { + fflib_ApexMocks mocks = new fflib_ApexMocks(); + fflib_ISObjectUnitOfWork mockUow = (fflib_ISObjectUnitOfWork)mocks.mock(fflib_ISObjectUnitOfWork.class); + TestUnitOfWorkFactory.setMock(mockUow); + // Given a custom DML class and a new record CustomDML customDML = new CustomDML(); Account myAccount = new Account(Name = 'Test Account'); // When the unit of work is instantiated from the Application Class and the record is registered and commited - fflib_ISObjectUnitOfWork unitOfWork = UnitOfWork.newInstance( + fflib_ISObjectUnitOfWork unitOfWork = TestUnitOfWorkFactory.newInstance( new List<SObjectType>{ Account.SObjectType }, customDML ); @@ -427,13 +486,16 @@ private class fflib_ApplicationTest @IsTest private static void callingMockedUnitOfWorkWithCustomObjectTypesAndDML() { + fflib_ApexMocks mocks = new fflib_ApexMocks(); + fflib_ISObjectUnitOfWork mockUow = (fflib_ISObjectUnitOfWork)mocks.mock(fflib_ISObjectUnitOfWork.class); + TestUnitOfWorkFactory.setMock(mockUow); + // Given a custom DML class and a new record CustomDML customDML = new CustomDML(); Account myAccount = new Account(Name = 'Test Account'); // When the unit of work is instantiated from the Application Class and the record is registered and commited - UnitOfWork.setMock(new fflib_SObjectMocks.SObjectUnitOfWork(new fflib_ApexMocks())); - fflib_ISObjectUnitOfWork uow = UnitOfWork.newInstance( + fflib_ISObjectUnitOfWork uow = TestUnitOfWorkFactory.newInstance( new List<SObjectType>{ Account.SObjectType }, customDML ); @@ -472,14 +534,14 @@ private class fflib_ApplicationTest } // Configure and create the ServiceFactory for this Application - public static final fflib_Application.ServiceFactory Service = + public static final fflib_Application.ServiceFactory TestServiceFactory = new fflib_Application.ServiceFactory( new Map<Type, Type> { IOpportunitiesService.class => OpportunitiesServiceImpl.class, - IAccountService.class => AccountsServiceImpl.class }); + IAccountsService.class => AccountsServiceImpl.class }); // Configure and create the UnitOfWorkFactory for this Application - public static final fflib_Application.UnitOfWorkFactory UnitOfWork = + public static final fflib_Application.UnitOfWorkFactory TestUnitOfWorkFactory = new fflib_Application.UnitOfWorkFactory( new List<SObjectType> { Account.SObjectType, @@ -487,29 +549,31 @@ private class fflib_ApplicationTest OpportunityLineItem.SObjectType }); // Configure and create the SelectorFactory for this Application - public static final fflib_Application.SelectorFactory Selector = + public static final fflib_Application.SelectorFactory TestSelectorFactory = new fflib_Application.SelectorFactory( new Map<SObjectType, Type> { Account.SObjectType => AccountsSelector.class, Opportunity.SObjectType => OpportuntiesSelector.class }); // Configure and create the DomainFactory for this Application - public static final fflib_Application.DomainFactory Domain = + public static final fflib_Application.DomainFactory TestDomainFactory = new fflib_Application.DomainFactory( - fflib_ApplicationTest.Selector, + fflib_ApplicationTest.TestSelectorFactory, new Map<SObjectType, Type> { Account.SObjectType => AccountsConstructor.class, Opportunity.SObjectType => OpportuntiesConstructor.class, Contact.SObjectType => ContactsConstructor.class }); - public class AccountsDomain extends fflib_SObjectDomain + public class Accounts + extends fflib_SObjectDomain + implements IAccounts { - public AccountsDomain(List<Account> sObjectList) + public Accounts(List<Account> sObjectList) { super(sObjectList); } - public AccountsDomain(List<SObject> sObjectList, SObjectType sObjectType) + public Accounts(List<SObject> sObjectList, SObjectType sObjectType) { super(sObjectList, sObjectType); } @@ -519,23 +583,25 @@ private class fflib_ApplicationTest { public fflib_SObjectDomain construct(List<SObject> sObjectList) { - return new AccountsDomain(sObjectList); + return new Accounts(sObjectList); } public fflib_SObjectDomain construct(List<SObject> sObjectList, SObjectType sObjectType) { - return new AccountsDomain(sObjectList, sObjectType); + return new Accounts(sObjectList, sObjectType); } } - public class OpportuntiesDomain extends fflib_SObjectDomain + public class Opportunties + extends fflib_SObjectDomain + implements IOpportunties { - public OpportuntiesDomain(List<Opportunity> sObjectList) + public Opportunties(List<Opportunity> sObjectList) { super(sObjectList); } - public OpportuntiesDomain(List<SObject> sObjectList, SObjectType sObjectType) + public Opportunties(List<SObject> sObjectList, SObjectType sObjectType) { super(sObjectList, sObjectType); } @@ -545,23 +611,25 @@ private class fflib_ApplicationTest { public fflib_SObjectDomain construct(List<SObject> sObjectList) { - return new OpportuntiesDomain(sObjectList); + return new Opportunties(sObjectList); } public fflib_SObjectDomain construct(List<SObject> sObjectList, SObjectType sObjectType) { - return new OpportuntiesDomain(sObjectList, sObjectType); + return new Opportunties(sObjectList, sObjectType); } } - public class ContactsDomain extends fflib_SObjectDomain + public class Contacts + extends fflib_SObjectDomain + implements IContacts { - public ContactsDomain(List<Opportunity> sObjectList) + public Contacts(List<Opportunity> sObjectList) { super(sObjectList); } - public ContactsDomain(List<SObject> sObjectList, SObjectType sObjectType) + public Contacts(List<SObject> sObjectList, SObjectType sObjectType) { super(sObjectList, sObjectType); } @@ -573,7 +641,9 @@ private class fflib_ApplicationTest } - class OpportuntiesSelector extends fflib_SObjectSelector + public class OpportuntiesSelector + extends fflib_SObjectSelector + implements IOpportuntiesSelector { public List<Schema.SObjectField> getSObjectFieldList() { @@ -589,7 +659,9 @@ private class fflib_ApplicationTest } } - class AccountsSelector extends fflib_SObjectSelector + public class AccountsSelector + extends fflib_SObjectSelector + implements IAccountsSelector { public List<Schema.SObjectField> getSObjectFieldList() { @@ -607,15 +679,23 @@ private class fflib_ApplicationTest } } + public interface IOpportunties extends fflib_ISObjectDomain { } + + public interface IAccounts extends fflib_ISObjectDomain { } + + public interface IContacts extends fflib_ISObjectDomain { } + + public interface IOpportuntiesSelector extends fflib_ISObjectSelector { } + + public interface IAccountsSelector extends fflib_ISObjectSelector { } + public interface IContactService { } public interface IOpportunitiesService { } - public interface IAccountService { } + public interface IAccountsService { } public class OpportunitiesServiceImpl implements IOpportunitiesService { } - public class AccountsServiceImpl implements IAccountService { } - - public class AccountsServiceMock implements IAccountService { } + public class AccountsServiceImpl implements IAccountsService { } } diff --git a/sfdx-source/apex-common/test/classes/mocks/fflib_SObjectMocks.cls b/sfdx-source/apex-common/test/classes/mocks/fflib_SObjectMocks.cls deleted file mode 100644 index b9e13ab12cb..00000000000 --- a/sfdx-source/apex-common/test/classes/mocks/fflib_SObjectMocks.cls +++ /dev/null @@ -1,237 +0,0 @@ -/** - * Copyright (c), FinancialForce.com, inc - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - Neither the name of the FinancialForce.com, inc nor the names of its contributors - * may be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**/ - -/* Generated by apex-mocks-generator version 4.0.0 */ -@isTest -public class fflib_SObjectMocks -{ - public virtual class SObjectDomain implements fflib_ISObjectDomain - { - private fflib_ApexMocks mocks; - - public SObjectDomain(fflib_ApexMocks mocks) - { - this.mocks = mocks; - } - - public Schema.SObjectType sObjectType() - { - return (Schema.SObjectType) mocks.mockNonVoidMethod(this, 'sObjectType', new List<Type> {}, new List<Object> {}); - } - - public List<SObject> getRecords() - { - return (List<SObject>) mocks.mockNonVoidMethod(this, 'getRecords', new List<Type> {}, new List<Object> {}); - } - - public Object getType() - { - return sObjectType(); - } - - public List<Object> getObjects() - { - return getRecords(); - } - } - - public virtual class SObjectSelector implements fflib_ISObjectSelector - { - private fflib_ApexMocks mocks; - - public SObjectSelector(fflib_ApexMocks mocks) - { - this.mocks = mocks; - } - - public Schema.SObjectType sObjectType() - { - return (Schema.SObjectType) mocks.mockNonVoidMethod(this, 'sObjectType', new List<Type> {}, new List<Object> {}); - } - - public List<SObject> selectSObjectsById(Set<Id> idSet) - { - return (List<SObject>) mocks.mockNonVoidMethod(this, 'selectSObjectsById', new List<Type> {Set<Id>.class}, new List<Object> {idSet}); - } - } - - public virtual class SObjectUnitOfWork implements fflib_ISObjectUnitOfWork - { - private fflib_ApexMocks mocks; - - public SObjectUnitOfWork(fflib_ApexMocks mocks) - { - this.mocks = mocks; - } - - public void registerNew(SObject record) - { - mocks.mockVoidMethod(this, 'registerNew', new List<Type> {SObject.class}, new List<Object> {record}); - } - - public void registerNew(List<SObject> records) - { - mocks.mockVoidMethod(this, 'registerNew', new List<Type> {List<SObject>.class}, new List<Object> {records}); - } - - public void registerNew(SObject record, Schema.sObjectField relatedToParentField, SObject relatedToParentRecord) - { - mocks.mockVoidMethod(this, 'registerNew', new List<Type> {SObject.class, Schema.sObjectField.class, SObject.class}, new List<Object> {record, relatedToParentField, relatedToParentRecord}); - } - - public void registerRelationship(SObject record, Schema.sObjectField relatedToField, SObject relatedTo) - { - mocks.mockVoidMethod(this, 'registerRelationship', new List<Type> {SObject.class, Schema.sObjectField.class, SObject.class}, new List<Object> {record, relatedToField, relatedTo}); - } - - public void registerRelationship(Messaging.SingleEmailMessage email, SObject relatedTo) - { - mocks.mockVoidMethod(this, 'registerRelationship', new List<Type> {Messaging.SingleEmailMessage.class, SObject.class}, new List<Object> {email, relatedTo}); - } - - public void registerRelationship(SObject record, Schema.sObjectField relatedToField, Schema.sObjectField externalIdField, Object externalId) - { - mocks.mockVoidMethod(this, 'registerRelationship', new List<Type> {SObject.class, Schema.sObjectField.class, Schema.sObjectField.class, Object.class}, new List<Object> {record, relatedToField, externalIdField, externalId}); - } - - public void registerDirty(SObject record) - { - mocks.mockVoidMethod(this, 'registerDirty', new List<Type> {SObject.class}, new List<Object> {record}); - } - - public void registerDirty(List<SObject> records, List<SObjectField> dirtyFields) - { - mocks.mockVoidMethod(this, 'registerDirty', new List<Type> { - SObject.class, System.Type.forName('List<SObjectField>') - }, new List<Object> { - records, dirtyFields - }); - } - - public void registerDirty(SObject record, List<SObjectField> dirtyFields) - { - mocks.mockVoidMethod(this, 'registerDirty', new List<Type> { - SObject.class, System.Type.forName('List<SObjectField>') - }, new List<Object> { - record, dirtyFields - }); - } - - public void registerDirty(SObject record, Schema.sObjectField relatedToParentField, SObject relatedToParentRecord) - { - mocks.mockVoidMethod(this, 'registerDirty', new List<Type> {SObject.class}, new List<Object> {record}); - } - - public void registerDirty(List<SObject> records) - { - mocks.mockVoidMethod(this, 'registerDirty', new List<Type> {List<SObject>.class}, new List<Object> {records}); - } - - public void registerUpsert(SObject record) - { - mocks.mockVoidMethod(this, 'registerUpsert', new List<Type> {List<SObject>.class}, new List<Object> {record}); - } - - public void registerEmptyRecycleBin(SObject record) - { - mocks.mockVoidMethod(this, 'registerEmptyRecycleBin', new List<Type> {List<SObject>.class}, new List<Object> {record}); - } - - public void registerEmptyRecycleBin(List<SObject> records) - { - mocks.mockVoidMethod(this, 'registerEmptyRecycleBin', new List<Type> {List<SObject>.class}, new List<Object> {records}); - } - - public void registerUpsert(List<SObject> records) - { - mocks.mockVoidMethod(this, 'registerUpsert', new List<Type> {List<SObject>.class}, new List<Object> {records}); - } - - public void registerDeleted(SObject record) - { - mocks.mockVoidMethod(this, 'registerDeleted', new List<Type> {SObject.class}, new List<Object> {record}); - } - - public void registerDeleted(List<SObject> records) - { - mocks.mockVoidMethod(this, 'registerDeleted', new List<Type> {List<SObject>.class}, new List<Object> {records}); - } - - public void registerPermanentlyDeleted(SObject record) - { - mocks.mockVoidMethod(this, 'registerPermanentlyDeleted', new List<Type> {SObject.class}, new List<Object> {record}); - } - - public void registerPermanentlyDeleted(List<SObject> records) - { - mocks.mockVoidMethod(this, 'registerPermanentlyDeleted', new List<Type> {SObject.class}, new List<Object> {records}); - } - - public void registerPublishBeforeTransaction(SObject record) - { - mocks.mockVoidMethod(this, 'registerPublishBeforeTransaction', new List<Type> {SObject.class}, new List<Object> {record}); - } - - public void registerPublishBeforeTransaction(List<SObject> records) - { - mocks.mockVoidMethod(this, 'registerPublishBeforeTransaction', new List<Type> {List<SObject>.class}, new List<Object> {records}); - } - - public void registerPublishAfterSuccessTransaction(SObject record) - { - mocks.mockVoidMethod(this, 'registerPublishAfterSuccessTransaction', new List<Type> {SObject.class}, new List<Object> {record}); - } - public void registerPublishAfterSuccessTransaction(List<SObject> records) - { - mocks.mockVoidMethod(this, 'registerPublishAfterSuccessTransaction', new List<Type> {List<SObject>.class}, new List<Object> {records}); - } - public void registerPublishAfterFailureTransaction(SObject record) - { - mocks.mockVoidMethod(this, 'registerPublishAfterFailureTransaction', new List<Type> {SObject.class}, new List<Object> {record}); - } - public void registerPublishAfterFailureTransaction(List<SObject> records) - { - mocks.mockVoidMethod(this, 'registerPublishAfterFailureTransaction', new List<Type> {List<SObject>.class}, new List<Object> {records}); - } - - - public void commitWork() - { - mocks.mockVoidMethod(this, 'commitWork', new List<Type> {}, new List<Object> {}); - } - - public void registerWork(fflib_SObjectUnitOfWork.IDoWork work) - { - mocks.mockVoidMethod(this, 'registerWork', new List<Type> {fflib_SObjectUnitOfWork.IDoWork.class}, new List<Object> {work}); - } - - public void registerEmail(Messaging.Email email) - { - mocks.mockVoidMethod(this, 'registerEmail', new List<Type> {Messaging.Email.class}, new List<Object> {email}); - } - } - -} \ No newline at end of file diff --git a/sfdx-source/apex-common/test/classes/mocks/fflib_SObjectMocks.cls-meta.xml b/sfdx-source/apex-common/test/classes/mocks/fflib_SObjectMocks.cls-meta.xml deleted file mode 100644 index 40d67933d00..00000000000 --- a/sfdx-source/apex-common/test/classes/mocks/fflib_SObjectMocks.cls-meta.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata"> - <apiVersion>54.0</apiVersion> - <status>Active</status> -</ApexClass>