Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Small enhancement to ReadMe #47

Open
cropredy opened this issue Aug 9, 2017 · 8 comments
Open

Small enhancement to ReadMe #47

cropredy opened this issue Aug 9, 2017 · 8 comments
Assignees

Comments

@cropredy
Copy link

cropredy commented Aug 9, 2017

For those of us who didn't come from a Java background and hence weren't exposed to Mockito, the Readme section when() dependency stubbing is maddeningly tantalizing. The obvious question one immediately asks is what if you don't care what the arg values are in the stubbed method? After much web searching and inspection of fflib_ApexMocksTest I realized there was a whole wealth of matchers that can be used not only in the verify() but also in the when()!

A small additional example in the Readme would inspire and direct the reader to the supported matchers in fflib_Match.

This framework is pretty powerful stuff but as

  • the related SFDC andyinthecloud pages are out of date (ref to generating Mocks class) and
  • the second edition book has syntax errors (uses factory() method instead of mock() method) and
  • the referenced blog posts are sprinkled with pre Stub API ....

Thus, getting the fflib / andyinthecloud online doc up to date / more comprehensive would go a long way towards increased adoption.

@dfruddffdc
Copy link
Contributor

Yes, I agree wholeheartedly. I'll try and sort some of these things out and report back after.

@dfruddffdc dfruddffdc self-assigned this Aug 12, 2017
@dfruddffdc
Copy link
Contributor

Hi cropredy, I finally got round to working on this.

We could definitely be doing a much better job with our docs, and you're right that it's a major barrier to adoption.

I think part of the problem is that the tests inside ApexMocks are a little contrived. So I put together a little SFDX sample app, with more realistic unit tests.

I'm using the Stub API, matchers, answers, and discuss different techniques for generating mocks and patterns for dependency injection - these are all covered in detail in the readme.
https://github.com/dfruddffdc/apex-mocks-sfdx

I'll port over the documentation into this repo's wiki at some point. Until then, hopefully my new sample app will help clarify things.

@cropredy
Copy link
Author

cropredy commented Nov 26, 2017 via email

@afawcett
Copy link
Contributor

@dfruddffdc nice work! 👍

@cropredy
Copy link
Author

cropredy commented Nov 28, 2017 via email

@afawcett
Copy link
Contributor

@cropredy thats an excellent tip, we should for sure reference that on the readme as being complementary. I also found that i wanted to mock complex selector responses and thus the following method was born, https://github.com/financialforcedev/fflib-apex-mocks/blob/master/src/classes/fflib_ApexMocksUtils.cls#L67.

@dfruddffdc
Copy link
Contributor

@cropredy Thanks for the detailed feedback, very useful!

@cropredyHelix
Copy link
Contributor

While puzzling over why one of my mocks wasn't working I reread the Readme.md last night and I had two additional thoughts:

  1. There is no link in the related refs to https://github.com/dfruddffdc/apex-mocks-sfdx which explains practical techniques for dependency injection
  2. AFAIK, there is no example in ApexMocks.Test that illustrates dependency injection for the fflib_MyList class that is used for all the testing.

Leading me to suggest that this section of the readme.md be enhanced as follows:

when() dependency stubbing

        // given mocks
	fflib_ApexMocks mocks = new fflib_ApexMocks();
	fflib_MyList.IList mockList = (fflib_MyList.IList)mocks.mock(fflib_MyList.class);

	mocks.startStubbing();
	mocks.when(mockList.get(0)).thenReturn('bob');
	mocks.when(mockList.get(1)).thenReturn('fred');
	mocks.stopStubbing();
      
        // given mocks injected (see also https://github.com/dfruddffdc/apex-mocks-sfdx)
        Bar b = new Bar(mockList);
        // when Bar invoked
        String result = b.doStuff();
        // then verify
        System.assertEquals(result, 'bob,fred','doStuff assembles a comma-separated list');

where the object under test is:

public class Bar 
  private fflib_MyList.IList myList;  // interface so real and mock can be used
  public Bar() {this.myList = new fflib_MyList.IList();} // normal PROD
  public Bar(fflib_MyList.IList mockMyList) {this.myList = mockMyList;} // for unit testing
              
  String public doStuff() {
  String[] resultVals = new List<String>(); 
  for (Integer i=0; i < 2; i++) {
    myList.add(i);
    resultVals.add(myList.get(i);
  }
  return String.join(resultVals,',');
}

So - why did I add this bit?

  • We use fflib patterns throughout our org; we use mock selectors, services, domains, and unitOfWork all the time. Those mocks get injected via (using selector as an example) Application.Selector.setMock(mocksSelector); and when the code executes a xxxSelector.newInstance().selectByXXX(..), the fflib_Application class returns the mocked selector via a factory rather than the PROD selector. All very neat - and somewhat magical to me and my team members who were introduced to fflib patterns.
  • But after living under the spell of this magic for months, we wanted to extend the use of apexmocks to classes that weren't services/domains/selectors. But that means you need to have a way to inject the mocks to the code under test. And none of the examples in this readme, fflib_ApexMocksTest or the related references show how to do this (at least for the StubApi implementation of apexMocks).
  • Of course, when writing this comment, I have now all figured this out but as this readme was my first port of call I thought this could help others.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants