scribble

Ben Brostoff

About Posts Book Recos Privacy Email GitHub

05 Aug 2017
RTD

RTD - Read the Docs. That phrase cuts across industries - I have heard it just as much as a programmer as I did as an investment banker. And while when said verbally, RTD (sometimes RTFD) usually lands with a hint of annoyance, I really believe it’s some of the most important career advice I have ever received.

I recently was writing some unit tests to check that a small wrapper around the AWS.SES API was invoked correctly and logging error messages as expected. Using sinon and the aws-sdk-mock library, I had some code that looked like the below to check error handling:

As background, mock from aws-sdk-mock takes three arguments, the third of which is a function that, in the case of mocking sendEmail, takes the email params and a callback. The callback itself takes two arguments - an error message and data from the response.

I received a comment from my boss on this code review to the effect that every time I was using callsFake, I could just be using callsArgWith. The documentation for callsArgWith points to callsArg:

stub.callsArgWith(index, arg1, arg2, …)

Like callsArg, but with arguments to pass to the callback.

stub.callsArg(index)

Causes the stub to call the argument at the provided index as a callback function. stub.callsArg(0); causes the stub to call the first argument as a callback.

It made sense - my only goal was to fake invoking the callback sendEmail takes following resolution of the email Promise. Giving it an error didn’t require passing in a new function to callsFake - sinon already offers this functionality:

sendEmailStub = sandbox.stub().callsArgWith(1, new Error());

And because you’re always one click a way in your IDE from seeing the source in node_modules:

after which there’s an easy path to cloning the source repo and after some investigation finding your way to callCallback in lib/sinon/behavior.js, which gets the callback using callArgAt set in the source we looked at, which then takes the callbackArguments sans the fake and position arguments passed in callsArgWith (note the function signature in the docs differs from what is the source - this is because addBehavior will always add functions to the stub prototype with the first argument being the stub itself).

Finally, here’s the test in sinon, clearly demonstrating that a callback passed as the second argument to a stub should be able to be passed any argument with callsArgWith:

In looking at the sinon docs and then the Amazon SES docs, I realized there was probably an ocean of API functionality I was not taking advantage of. And the only way to find out would be to study and experiment. Which is the fun of being an engineer.

I bring up this example because I think it illustrates the importance of reading documentation (and even better, source code). I was familiar with callsFake, so every testing situation looked like a nail to its hammer. This is what happens when API docs are read quickly and with the intent of completing a task. The cost is that robust APIs are used incorrectly, and code that should be short and sweet becomes long and ugly.

I know this seems obvious, but I wanted to write about it because I know there are different gradients of RTD. In banking, you might read the earnings call transcript but not the 10-Q; only the part of the S-1 with the risks to the business; the first tab of the huge Excel model.

In programming, there’s cherry-picking documentation; reading the documentation without the source code; starting a project with “getting started” documentation and never revisiting the docs again, and so much more.

A lot of this can be argued against with allusions to time management principles. How am I supposed to get anything done if I’m reading forty thousands pages of documentation and source code? Obviously, reading all the documentation - especially for something like the AWS SDK - is impossible. But transferring a 3 hour chunk of time from 70 / 30 writing code / reading docs to 65 / 35 writing code / reading docs?

You might end up improving your code and reading some interesting source code from a great library


scribble

About Posts Book Recos Privacy Email GitHub