Code Monkey home page Code Monkey logo

Comments (6)

donnie745 avatar donnie745 commented on May 28, 2024 1

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: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.

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!


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.

dfruddffdc avatar dfruddffdc commented on May 28, 2024

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.

donnie745 avatar donnie745 commented on May 28, 2024

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.

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!


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.

dfruddffdc avatar dfruddffdc commented on May 28, 2024

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.

donnie745 avatar donnie745 commented on May 28, 2024

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.

dfruddffdc avatar dfruddffdc commented on May 28, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.