Comments (6)
Hello again,
Referring back to the proposed solution in my previous email for generating
mocks that implement multiple interfaces, I have just realised Apex does
not allow classes to be extended unless the class is explicitly declared as
virtual or abstract. Is there any syntax within the
interfacemocks.properties that would allow for the generation tool to
declare the generated mock class as virtual rather than having to hand-edit
the generated classes manually after mock generation?
Cheers,
Donnie
On 6 September 2016 at 11:12, Donnie Macleod [email protected] wrote:
Excellent, thanks for that. In my second week of Salesforce development so
hadn't appreciated the complexities you mentioned above. This will resolve
my issue for the particular test mock classes I was wanting to generate.I guess there is a bit of complication if we wish to mock a class that
implements more than 1 interface (e.g. a class implementing mix-in
interfaces) then.For example, given we have a class MySuperClass that implements mixin
interfaces IMyBaseIntefaceA, IMyBaseInterfaceB and IMyBaseInterfaceC, would
I be right in thinking the only workaround for this would be as below?:
i) Create an interface IMyBaseInterfaceAB that extends IMyBaseInterfaceA
and explicitly declares all methods that are in IMyBaseInterfaceB in its
interface body.
ii) Create an interface IMyBaseInterfaceABC that
extends IMyBaseInterfaceAB and explicitly declares all methods that are
in IMyBaseInterfaceC in its interface body.
iii) Have the following in the interfacemocks.properties file:
IMyBaseInterfaceA=BaseInterfaceA
IMyBaseInterfaceB=BaseInterfaceB
IMyBaseInterfaceC=BaseInterfaceC
IMyBaseInterfaceAB=BaseInterfaceAB:BaseInterfaceA
IMyBaseInterfaceABC=BaseInterfaceABC:BaseInterfaceABAlthough it's not an ideal solution with the extra interfaces purely for
mocking and having to ensure the developers take care to keep the
explicitly declared methods within these extra interfaces (i.e. all the
methods except for those in the first mix-in interface IMyBaseInterfaceA)
in sync with any changes that may occur over time to the actual mix-in
interfaces, it seems that this is the only way to do this. Would I be
correct saying that?Hope the above doesn't read as too much gibberish but your input would be
welcome!Kind regards,
DonnieOn 6 September 2016 at 09:40, David F [email protected] wrote:
Hi Donnie,
The ApexMocks Generator has no real knowledge of Apex syntax.
It parses the plain text in the static code files. Parsing text is
inherently risky, so we expect the files to be in a certain format and
don't attempt to traverse the interface inheritance hierarchy.Not only would it be generally difficult to find the parent interface
definition, but the parent interface might not even be in the static code -
if you are extending a native interface such as System.Schedulable, or a
global interface defined in another managed package.There are ways around this however, as demonstrated in the apex-common
sample app.
- interfacemocks.properties
https://github.com/financialforcedev/fflib-apex-common-samplecode/blob/master/interfacemocks.properties- fflib_SObjectMocks.cls
https://github.com/financialforcedev/fflib-apex-common/blob/master/fflib/src/classes/fflib_SObjectMocks.cls- Mocks.cls
https://github.com/financialforcedev/fflib-apex-common-samplecode/blob/master/fflib-sample-code/src/classes/Mocks.clsTo put it in the context of your examples above, you should generate
mocks classes for both interfaces.interfacemocks.properties:
IBaseInterface=BaseInterface
ISuperInterface=SuperInterface:BaseInterfaceThis will generate 2 classes. The Mocks.SuperInterface extends the
BaseInterface, and therefore defines a public void MyBaseMethod() method
and can be mocked as normal.I'm going to mark this case as closed, but obviously get back in touch if
anything I've written here doesn't make sense!—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
#26 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AD-jOo5L9jjx_q8rGC5xgM4jG6_ViU9eks5qnSbpgaJpZM4JzjVy
.
from fflib-apex-mocks.
Hi Donnie,
The ApexMocks Generator has no real knowledge of Apex syntax.
It parses the plain text in the static code files. Parsing text is inherently risky, so we expect the files to be in a certain format and don't attempt to traverse the interface inheritance hierarchy.
Not only would it be generally difficult to find the parent interface definition, but the parent interface might not even be in the static code - if you are extending a native interface such as System.Schedulable, or a global interface defined in another managed package.
There are ways around this however, as demonstrated in the apex-common sample app.
To put it in the context of your examples above, you should generate mocks classes for both interfaces.
interfacemocks.properties:
IBaseInterface=BaseInterface
ISuperInterface=SuperInterface:BaseInterface
This will generate 2 classes. The Mocks.SuperInterface extends the BaseInterface, and therefore defines a public void MyBaseMethod()
method and can be mocked as normal.
I'm going to mark this case as closed, but obviously get back in touch if anything I've written here doesn't make sense!
from fflib-apex-mocks.
Excellent, thanks for that. In my second week of Salesforce development so
hadn't appreciated the complexities you mentioned above. This will resolve
my issue for the particular test mock classes I was wanting to generate.
I guess there is a bit of complication if we wish to mock a class that
implements more than 1 interface (e.g. a class implementing mix-in
interfaces) then.
For example, given we have a class MySuperClass that implements mixin
interfaces IMyBaseIntefaceA, IMyBaseInterfaceB and IMyBaseInterfaceC, would
I be right in thinking the only workaround for this would be as below?:
i) Create an interface IMyBaseInterfaceAB that extends IMyBaseInterfaceA
and explicitly declares all methods that are in IMyBaseInterfaceB in its
interface body.
ii) Create an interface IMyBaseInterfaceABC that extends IMyBaseInterfaceAB
and explicitly declares all methods that are in IMyBaseInterfaceC in its
interface body.
iii) Have the following in the interfacemocks.properties file:
IMyBaseInterfaceA=BaseInterfaceA
IMyBaseInterfaceB=BaseInterfaceB
IMyBaseInterfaceC=BaseInterfaceC
IMyBaseInterfaceAB=BaseInterfaceAB:BaseInterfaceA
IMyBaseInterfaceABC=BaseInterfaceABC:BaseInterfaceAB
Although it's not an ideal solution with the extra interfaces purely for
mocking and having to ensure the developers take care to keep the
explicitly declared methods within these extra interfaces (i.e. all the
methods except for those in the first mix-in interface IMyBaseInterfaceA)
in sync with any changes that may occur over time to the actual mix-in
interfaces, it seems that this is the only way to do this. Would I be
correct saying that?
Hope the above doesn't read as too much gibberish but your input would be
welcome!
Kind regards,
Donnie
On 6 September 2016 at 09:40, David F [email protected] wrote:
Hi Donnie,
The ApexMocks Generator has no real knowledge of Apex syntax.
It parses the plain text in the static code files. Parsing text is
inherently risky, so we expect the files to be in a certain format and
don't attempt to traverse the interface inheritance hierarchy.Not only would it be generally difficult to find the parent interface
definition, but the parent interface might not even be in the static code -
if you are extending a native interface such as System.Schedulable, or a
global interface defined in another managed package.There are ways around this however, as demonstrated in the apex-common
sample app.
- interfacemocks.properties
https://github.com/financialforcedev/fflib-apex-common-samplecode/blob/master/interfacemocks.properties- fflib_SObjectMocks.cls
https://github.com/financialforcedev/fflib-apex-common/blob/master/fflib/src/classes/fflib_SObjectMocks.cls- Mocks.cls
https://github.com/financialforcedev/fflib-apex-common-samplecode/blob/master/fflib-sample-code/src/classes/Mocks.clsTo put it in the context of your examples above, you should generate mocks
classes for both interfaces.interfacemocks.properties:
IBaseInterface=BaseInterface
ISuperInterface=SuperInterface:BaseInterfaceThis will generate 2 classes. The Mocks.SuperInterface extends the
BaseInterface, and therefore defines a public void MyBaseMethod() method
and can be mocked as normal.I'm going to mark this case as closed, but obviously get back in touch if
anything I've written here doesn't make sense!—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
#26 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AD-jOo5L9jjx_q8rGC5xgM4jG6_ViU9eks5qnSbpgaJpZM4JzjVy
.
from fflib-apex-mocks.
Hi again Donnie,
It certainly looks like you're getting the hang of this library!
I have good news and bad news, but hey, the bad news has a silver lining.
So good news first: you can mark generated classes as virtual. Put a hash in your property to control the class modifiers, in case you want to change the class visibility, sharing mode etc.
IMyBaseInterfaceA=BaseInterfaceA#public virtual with sharing
Bad news: I don't think you'll be able to generate the mock MySuperClass that implements mixin
interfaces IMyBaseIntefaceA, IMyBaseInterfaceB and IMyBaseInterfaceC. As Apex doesn't allow an interface to extend more than 1 other interface, I can't see how you would make a IMyBaseInterfaceABC an instanceof IMyBaseInterfaceA+B+C.
We've encountered similar limitations internally. The inelegant, but viable, workaround is to create the mock class manually - you can use the generator to create a starting point mock class.
The good news is that you will be able to achieve this with the stub API, with no need for IMyBaseInterfaceABC. Look out for it at Dreamforce :)
https://success.salesforce.com/Sessions?eventId=a1Q3000000qQOd9EAG#/session/a2q3A000000LBS8QAO
from fflib-apex-mocks.
Hi David,
Thanks for that, will use the hash syntax to specify the class modifiers to
sort the problem then. The solution for the mixins doesn't involve
extending two interfaces so the mocks for the example with the three
interfaces will generate BaseInterfaceABC with all the methods from the
three interfaces, the only problem being that BaseInterfaceABC instanceof
IInterfaceB and BaseInterfaceABC instanceof IInterfaceC are both false
(only IInterfaceA is actually extended) so it's not an ideal solution!
Looking forward to the introduction of the Stub API though to make things a
lot easier for unit testing, without holding you to any specific dates
would you have a rough idea when the Stub API will be generally available?
Thanks again for all your help:-)
Cheers,
Donnie
On 9 September 2016 at 21:41, David F [email protected] wrote:
Hi again Donnie,
It certainly looks like you're getting the hang of this library!
I have good news and bad news, but hey, the bad news has a silver lining.So good news first: you can mark generated classes as virtual. Put a
hash in your property to control the class modifiers, in case you want to
change the class visibility, sharing mode etc.IMyBaseInterfaceA=BaseInterfaceA#public virtual with sharing
Bad news: I don't think you'll be able to generate the mock MySuperClass
that implements mixin
interfaces IMyBaseIntefaceA, IMyBaseInterfaceB and IMyBaseInterfaceC. As
Apex doesn't allow an interface to extend more than 1 other interface, I
can't see how you would make a IMyBaseInterfaceABC an instanceof
IMyBaseInterfaceA+B+C.We've encountered similar limitations internally. The inelegant, but
viable, workaround is to create the mock class manually - you can use the
generator to create a starting point mock class.The good news is that you will be able to achieve this with the stub API,
with no need for IMyBaseInterfaceABC. Look out for it at Dreamforce :)
https://success.salesforce.com/Sessions?eventId=
a1Q3000000qQOd9EAG#/session/a2q3A000000LBS8QAO—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
#26 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AD-jOlO2ovt_LMl4SU0Q3cCwnjk7giMFks5qocR3gaJpZM4JzjVy
.
from fflib-apex-mocks.
Agree, it's not ideal but good to hear you've got something you can work with for now.
Stub API is in pilot in Winter 17, so we're looking at maybe Spring/Summer 17 for general availability.
from fflib-apex-mocks.
Related Issues (20)
- Explore the feasibility to support @NamespaceAccessible HOT 1
- How to use Apex Mock Framework for Custom Setting Records? HOT 3
- Heroku error when trying to deploy the repository
- No jar file? HOT 1
- Install help needed HOT 4
- fflib_MyList has 0 coverage when I run MockTest. Is that normal? HOT 1
- Mark all classes as @IsTest?
- makeRelationship does not work with Junction Objects HOT 1
- Add a method to allow us to create any SObjects with any NON WRITABLE Field HOT 2
- How to verify a Method was called N times? HOT 3
- Why do we must pass an Interface to set a service mock? HOT 2
- There is no way to mock void methods HOT 2
- renderStoredEmailTemplate returns with an error System.EmailTemplateRenderException: INVALID_CROSS_REFERENCE_KEY: invalid cross reference id when passing Ids generated from fflib_IDGenerator HOT 1
- README.md out of date? HOT 1
- Deploy to salesforce is not working HOT 12
- Can't deploy to production HOT 2
- Unable to deploy to developer org with Unhandled Exception HOT 1
- Multiple domain mocks HOT 4
- IDGenerator : Generating Salesforce Object ID under the new structure HOT 3
- Code Coverage Issue with fflib_InvocationOnMock Class HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fflib-apex-mocks.