@@ -42,6 +42,18 @@ private class fflib_ApplicationTest
4242 System .assert (domainObjectAcct instanceof AccountsDomain );
4343 System .assertEquals (testAccountId , domainObjectAcct .getRecords ()[0 ].Id );
4444
45+ // Registered Accounts domain class by SObject List
46+ testAccountId = fflib_IDGenerator .generate (Account .SObjectType );
47+ domainObjectAcct =
48+ Domain .newInstance (
49+ new List <SObject >
50+ { new Account (
51+ Id = testAccountId ,
52+ Name = ' Test Account' ) }
53+ , Account .SObjectType );
54+ System .assert (domainObjectAcct instanceof AccountsDomain );
55+ System .assertEquals (testAccountId , domainObjectAcct .getRecords ()[0 ].Id );
56+
4557 // Registered Opportunities domain class by SObject List
4658 Id testOpportunityId = fflib_IDGenerator .generate (Opportunity .SObjectType );
4759 fflib_ISObjectDomain domainObjectOpp =
@@ -53,6 +65,19 @@ private class fflib_ApplicationTest
5365 System .assertEquals (testOpportunityId , domainObjectOpp .getRecords ()[0 ].Id );
5466 System .assert (domainObjectOpp instanceof OpportuntiesDomain );
5567
68+ // Test failure for creating new instance using IConstructable2
69+ // for domain class that does not support it
70+ testOpportunityId = fflib_IDGenerator .generate (Opportunity .SObjectType );
71+ domainObjectOpp =
72+ Domain .newInstance (
73+ new List <SObject >
74+ { new Opportunity (
75+ Id = testOpportunityId ,
76+ Name = ' Test Opportunity' ) }
77+ , Opportunity .SObjectType );
78+ System .assertEquals (testOpportunityId , domainObjectOpp .getRecords ()[0 ].Id );
79+ System .assert (domainObjectOpp instanceof OpportuntiesDomain );
80+
5681 // Given
5782 fflib_ApexMocks mocks = new fflib_ApexMocks ();
5883 mocks .startStubbing ();
@@ -71,6 +96,18 @@ private class fflib_ApplicationTest
7196
7297 // Then
7398 System .assert (domainObjectAcct instanceof fflib_SObjectMocks .SObjectDomain );
99+
100+ // When
101+ domainObjectAcct =
102+ Domain .newInstance (
103+ new List <SObject >
104+ { new Account (
105+ Id = testAccountId ,
106+ Name = ' Test Account' ) }
107+ , Account .SObjectType );
108+
109+ // Then
110+ System .assert (domainObjectAcct instanceof fflib_SObjectMocks .SObjectDomain );
74111 }
75112
76113 @IsTest
@@ -115,6 +152,17 @@ private class fflib_ApplicationTest
115152 }
116153 }
117154
155+ @IsTest
156+ private static void callingDomainFactoryWithNoSObjectTypeShouldGiveException ()
157+ {
158+ try {
159+ Domain .newInstance (new List <SObject >(), null );
160+ System .assert (false , ' Expected exception' );
161+ } catch (fflib_Application .DeveloperException e ) {
162+ System .assertEquals (' Must specify sObjectType' , e .getMessage ());
163+ }
164+ }
165+
118166 @IsTest
119167 private static void callingDomainFactoryWithInAccessableConstructorShouldGiveException ()
120168 {
@@ -124,8 +172,33 @@ private class fflib_ApplicationTest
124172 } catch (fflib_Application .DeveloperException e ) {
125173 System .assertEquals (' Domain constructor class not found for SObjectType Product2' , e .getMessage ());
126174 }
175+
176+ try {
177+ Domain .newInstance (new List <SObject >{ new Product2 (Name = ' Test Product' ) }, Product2 .SObjectType );
178+ System .assert (false , ' Expected exception' );
179+ } catch (fflib_Application .DeveloperException e ) {
180+ System .assertEquals (' Domain constructor class not found for SObjectType Product2' , e .getMessage ());
181+ }
127182 }
128183
184+ @IsTest
185+ private static void callingDomainFactoryWithContructorClassThatDoesNotSupportIConstructableShouldGiveException ()
186+ {
187+ try {
188+ Domain .newInstance (new List <Contact >{ new Contact (LastName = ' TestContactLName' ) });
189+ System .assert (false , ' Expected exception' );
190+ } catch (System .TypeException e ) {
191+ System .assertEquals (' Invalid conversion from runtime type fflib_ApplicationTest.ContactsConstructor to fflib_SObjectDomain.IConstructable' , e .getMessage ());
192+ }
193+
194+ try {
195+ Domain .newInstance (new List <SObject >{ new Contact (LastName = ' TestContactLName' ) }, Contact .SObjectType );
196+ System .assert (false , ' Expected exception' );
197+ } catch (System .TypeException e ) {
198+ System .assertEquals (' Invalid conversion from runtime type fflib_ApplicationTest.ContactsConstructor to fflib_SObjectDomain.IConstructable2' , e .getMessage ());
199+ }
200+ }
201+
129202 @IsTest
130203 private static void callingUnitOfWorkFactoryShouldGivenStandardImplsAndMockImpls ()
131204 {
@@ -302,22 +375,33 @@ private class fflib_ApplicationTest
302375 fflib_ApplicationTest .Selector ,
303376 new Map <SObjectType , Type > {
304377 Account .SObjectType = > AccountsConstructor .class ,
305- Opportunity .SObjectType = > OpportuntiesConstructor .class });
378+ Opportunity .SObjectType = > OpportuntiesConstructor .class ,
379+ Contact .SObjectType = > ContactsConstructor .class });
306380
307381 public class AccountsDomain extends fflib_SObjectDomain
308382 {
309383 public AccountsDomain (List <Opportunity > sObjectList )
310384 {
311385 super (sObjectList );
312386 }
387+
388+ public AccountsDomain (List <SObject > sObjectList , SObjectType sObjectType )
389+ {
390+ super (sObjectList , sObjectType );
391+ }
313392 }
314393
315- public class AccountsConstructor implements fflib_SObjectDomain .IConstructable
394+ public class AccountsConstructor implements fflib_SObjectDomain .IConstructable2
316395 {
317396 public fflib_SObjectDomain construct (List <SObject > sObjectList )
318397 {
319398 return new AccountsDomain (sObjectList );
320399 }
400+
401+ public fflib_SObjectDomain construct (List <SObject > sObjectList , SObjectType sObjectType )
402+ {
403+ return new AccountsDomain (sObjectList , sObjectType );
404+ }
321405 }
322406
323407 public class OpportuntiesDomain extends fflib_SObjectDomain
@@ -326,15 +410,44 @@ private class fflib_ApplicationTest
326410 {
327411 super (sObjectList );
328412 }
413+
414+ public OpportuntiesDomain (List <SObject > sObjectList , SObjectType sObjectType )
415+ {
416+ super (sObjectList , sObjectType );
417+ }
329418 }
330419
331- public class OpportuntiesConstructor implements fflib_SObjectDomain .IConstructable
420+ public class OpportuntiesConstructor implements fflib_SObjectDomain .IConstructable2
332421 {
333422 public fflib_SObjectDomain construct (List <SObject > sObjectList )
334423 {
335424 return new OpportuntiesDomain (sObjectList );
336425 }
337- }
426+
427+ public fflib_SObjectDomain construct (List <SObject > sObjectList , SObjectType sObjectType )
428+ {
429+ return new OpportuntiesDomain (sObjectList , sObjectType );
430+ }
431+ }
432+
433+ public class ContactsDomain extends fflib_SObjectDomain
434+ {
435+ public ContactsDomain (List <Opportunity > sObjectList )
436+ {
437+ super (sObjectList );
438+ }
439+
440+ public ContactsDomain (List <SObject > sObjectList , SObjectType sObjectType )
441+ {
442+ super (sObjectList , sObjectType );
443+ }
444+ }
445+
446+ // Intentionally does not support IConstructable or IConstructable2 interfaces in order to support testing
447+ public class ContactsConstructor
448+ {
449+
450+ }
338451
339452 class OpportuntiesSelector extends fflib_SObjectSelector
340453 {
0 commit comments