Sign in

I like making things and solving problems. http://nikhilvijayan.com.
Image from: https://www.flaticon.com/free-icon/paint-bucket_103998

I found it a bit hard to find out how to mock AWS S3 while using Jest. So, I thought I’d document it here.

Useful Stack Overflow answers:

Here’s the code we will be testing

Here’s a unit test for the code above using Jest

We’ll be mocking S3, and asserting that S3’s copyObject function gets called with the right parameters.

Obviously, this is a simplistic function with hard-coded values, but the test is valid for a function that maybe does some transformation to the destination key, or does some validation on the CopySource, etc.

Some things to note

In the mockS3Instance I am using .mockReturnThis() . This is used to allow for chaining it to another method (in…


If, like me, you’ve spent way too long wondering what GraphQL is because sentences like query language for your API makes no sense to you. This blog post is for you.

In a REST API world, you have various endpoints to get, put and delete resources, right?

Let’s say we have an app that manages a leaderboard and we have the following routes:

POST /score/:playerId
GET /score/:playerId
GET /leaderboard/:leaderboardId
PUT /leaderboard/:leaderboardId

Now, say we have 6 players that are part of a leaderboard, on initial load we want to load up the state of the leaderboard, which includes all player…


I’m writing this for all of you who’ve been searching for terms like:

  • How to test stdout in Node
  • How to spy on stdout in Node using Jest
  • How to stub stdout in Node

It took me a day, but thanks to my colleague James Ransome for suggesting the use of Node’s child_process for this, it was fairly easy in the end!

Note: If you’re in a hurry, I’ve put together a repo that you can clone here: https://github.com/nkhil/testing-stdout

I wanted to test Pino’s output to stdout

Note: I know this counts as testing implementation details of a dependency, but in this case I was working on a…


This is a quick gotcha if you keep getting BadRequest without a useful error message trying to connect another container to localstack S3.

Here’s part of the error I was getting:

  message: null,
code: 'BadRequest',
region: null,
time: 2020-12-02T13:41:48.630Z,
requestId: null,
extendedRequestId: undefined,
cfId: undefined,
statusCode: 400,
retryable: false,
retryDelay: 85.98033816170914
}"

If you’re getting this error, check if you’ve specified a DEFAULT_REGION in the docker-compose.yml file.

Here’s what my docker-compose.yml looked like:

# docker-compose.ymllocalstack:    
networks:
testing_net:
ipv4_address: 172.28.1.9
image: localstack/localstack:latest
environment:
- SERVICES=s3:4566
- DEFAULT_REGION=us-east-1 👈 THE CULPRIT! …


First copy the contents of this docker-compose.yml file listed in the localstack repository into a local directory (make sure the file name is not changed).

Run up the container with docker-compose up. This will get localstack running locally.

At the time of writing this post (Oct 2020), the S3 service is available on port 4566 (i.e. http://localhost:4566)

Install the aws / localstack wrapper

Install awscli-local from here as a wrapper around localstack. This will allow you to use awslocal in your command line, which is very close to the aws command usage.

Create a new bucket

awslocal s3api create-bucket --bucket business-time-nonprod --region eu-west-1# You don't need the region flag…


Every time you require a file in node, these are the 5 things that take place:

  • Resolve
  • Load
  • Wrap
  • Evaluate
  • Cache

Resolve

Node will attempt to map the string given to require() into a path on the file system. This path could be local to node, under nodule_modules folder, or node modules under a parent directory or any other path.

Load

Node will then load the contents of this file into memory

Wrap

Wraps the content of the file with an IIFE (I’ve discussed this IIFE in another blog post How require and module.exports in node works)

Evaluate

Node will then evaluate the file…


I’ve always wondered how you always have access to require and module.exports in any .js files running with node. I recently found something cool.

If you console.log arguments in a file, and run it with node. For eg:

// someFile.js
console.log(arguments);

We actually get arguments:

[Arguments] {
'0': {},
'1': [Function: require] {
resolve: [Function: resolve] { paths: [Function: paths] },
main: Module {
id: '.',
path: '/someFolder',
exports: {},
parent: null…


This is a quick tutorial on setting up a simple express service using swagger 3.0.

Here’s the Github repo if you want to jump straight into the code: https://github.com/nkhil/swagger-3-setup.

Note: If you’d like to know why creating API definitions might be a good idea, this is a good read.

The biggest advantage of Swagger 3.0 that I’ve discovered are:

  • Request and response validation out of the box
  • Operation handlers to replace routers

Request & response validation

Let’s say our service has a GET route called /healthcheck/ready that we call to determine the readiness of the service.

We don’t want just anyone calling this route…


An easy solution that we can build from scratch to handle object grouping

Here’s the array we’re starting off with:

We now want to group this array. We can do this by artist, or by year.

Here are the results we want:

Group by year

Group by artist

Implementation

Explanation

Our groupBy function is a curried function that makes use of partial application to help keep this function re-usable.

The groupBy function takes a key (eg: 'year') as its only argument, and returns another function group, which in turn takes the array of objects that we'd like to sort.

Within the group function, we're reducing the array using an empty object as the accumulator (because that's the…


loosely linked picture to spies, or something

This is a unit test example to confirm that a particular function is called with the right parameters.

The code

In the code above, we have two functions calculateTotal and updateTotal. To test that they work correctly for a given input, we’re going to test that the databaseUpdater function is called with the correct parameters.

Using proxyquire and sinon spies

Proxyquire is a package that lets you stub modules that you require into your code.

Here’s a quick example of how you can use proxyquire

Breaking it down

const databaseUpdaterSpy = sinon.spy();
const stub = {
'../model/databaseUpdater': databaseUpdaterSpy,
};

Here, I’m using chai as the assertion library, sinon

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store