Skip to content

Instantly share code, notes, and snippets.

@LoganBarnett
Created November 16, 2017 19:00
Show Gist options
  • Save LoganBarnett/7567cd777631a69db867770c9659d5f2 to your computer and use it in GitHub Desktop.
Save LoganBarnett/7567cd777631a69db867770c9659d5f2 to your computer and use it in GitHub Desktop.
Use a dependency-injection like function to make mocking easier
// Generally I suffix these variables with "Fn" so I know I have to call it before I can use the interesting bits.
const fooFn = require('./foo.js')
const aws = require('aws')
// Variant 1: This is the simplest thing that can happen.
fooFn(aws.send)
// Variant 2: If send is a method and not a function (implicit "this"), then we need to bind it. Simply passing send doesn't include its "this" context. Functions have a bind function that produces a new function with the binding you want.
fooFn(aws.send.bind(aws))
// Variant 3: Perhaps the send function has some parameters in it that are very AWS specific, or maybe even environment specific. We can move any kind of configuration send would need into the responsibilities of this file, and then foo.js just cares about when the right time to invoke/handle send is. Again, bind is our friend here. The first argument is the context or the "this" reference (see variant 2 above). The following rest args are parameters are a "baked" into the function that results from bind. If send needs some URL to point to in its first arg, we would do something like this:
fooFn(aws.send.bind(aws, config.fooLambdaUrl))
// If aws.send has a signature like (url, a, b) => result, then the resulting function will have a signature of (a, b) => result. The URL simply is implied at this point.
// Note that it's "send" and not "awsSend" - we don't care about aws anymore here!
module.exports = (send) => {
return {
invokeLambda: (args) => {
// Your app might be more complicated than this, but the effect is invokeLambda will be greatly simplified.
send(args)
},
}
}
// Notice we don't even pull in the aws module here.
const fooFn = require('./foo.js')
it('invokes the aws send function at the right time only once', () => {
const spy = jasmine.createSpy('aws.send')
fooFn(spy).send()
expect(spy).shouldHaveBeenCalledWith('stuff')
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment