Closed gesta22 closed 1 year ago
Hi @gesta22. Like you've done for the mockCaseSelector
, you must mock that sObjectType()
method for the Domains, enabling the factory to register the classes for the corresponding SObjectType.
Also as an observational note, the best practice for creating a mock is using the related Interface as opposed to the concrete class, although it works. The reasoning is ensuring that the interfaces match the classes. By mocking the concrete class it's possible the existence of an undocumented, in the interface, method could slip through testing. For instance, a developer might have added xyzMethod(...)
to the class but forgot to add it to the interface, which would not be detected when testing with a mock of the concrete class.
An interpretation of the Issue's code using the interfaces.
fflib_ApexMocks mocks = new fflib_ApexMocks();
IBPP_CaseSelector mockCaseSelector = (IBPP_CaseSelector)mocks.mock(IBPP_CaseSelector.class);
IBPP_Cases mockCaseDomain = (IBPP_Cases)mocks.mock(IBPP_Cases.class);
IBPP_CaseEntityAssociations mockCaseEntityDomain = (IBPP_CaseEntityAssociations)mocks.mock(IBPP_CaseEntityAssociations.class);
If anyone interested, it got resolved after I stubbed this method for all domains:
mocks.when(mockDomain.sObjectType()).thenReturn(MyObject__c.SObjectType);
@stohn777 Not sure I'm getting your point on interfaces. Class don't have to be related to just 1 interface. What if my domain class implements several interfaces?
@gesta22
Initially this thread was talking about Selectors, and the typical pattern is creating an interface for the selector that extends fflib_SObjectSelector
. In the snippets of your code, you would have an IBPP_CaseSelector
Interface. This is the what would be registered with the Application.Selector
factory. It's true that the selector might implement other interfaces, but this would be the one that's relevant to the factory pattern.
Domains would generally exhibit the same pattern. The relevant interface would be the one extending fflib_ISObjectDomain
and would be used to configure the pattern or leveraged when creating mocks.
I hope that provides a bit of clarification.
I was not able to create mocks for several domain classes in my test method.
Here is my unit test, that's not working:
During the debug I found out that in following lines second domain.setMock() overwrites the firts one, so mocks for mockCaseDomain are not working, it calls actual code instead of mock.
I assume there should be some way to mock several domains, selectors etc. in one unit test, as it's quite common scenario that we need to get some info from several objects in one method. But I was not able to find any examples online, so not sure, if that's possibe at all. And if not, how would you overcome such scenarios?
Also, just a note, if I remove mockCaseDomain from this unit test and hard code actual condition I will receive from this domain, test works fine, so I assume, all coding is done correctly.