loading...

Helpful Node.js testing utilities

shalvah profile image Shalvah Updated on ・3 min read

This is not a post about Node.js' testing frameworks, assertion libraries or mocking libraries like Jest, Chai, Mocha and Sinon. This is a short list of libraries that provide functionality that has helped me set up an effective test environment.

Decache

This is my number 1 tool when testing a library I'm building that stores global state. Here's what their readme says:

In node.js when you require() a module, node stores a cached version of the module, so that all subsequent calls to require() do not have to reload the module from the filesystem.
decache ( Delete Cache ) lets you delete modules from node.js require() cache

I used decache in my event management library, Burns. I use it to restore the state of the module being tested in an afterEach hook. This is especially important as Burns keeps track of global state.

Mitm

Mitm is a package for intercepting network calls (TCP or HTTP) dispatched from your code.
I 've used mitm to fake responses from the Twitter API in my Twitter reminders bot, @RemindMe_OfThis. It allows me to basically do whatever I like, such as recording the requests and responding differently depending on the request data.

mock-require

mock-require allows you override require calls by specifying what should be returned when a particular module is returned. I used it multiple times in @RemindMe_OfThis to return my own fakes for dependencies my code needed.

Now, some folks would probably say I should have used dependency injection instead, in which case I could easily inject my mocks without having to use mock-require or hack Node.js' module system. They're probably right. However, in my experience, it's been quite painful (and overkill) implementing DI in Node.js (especially when there's no static typing). I prefer to stick with the straightforward approach—the module system.😀

Some alternatives to mock-require:

  • rewire: This does a similar job, and more, but you have to replace your require call with rewire and then manually specify the mocks. One advantage of that is that you're only mocking for that instance, not globally. This didn't fit my use case, though.
  • proxyquire: Similar to rewire, it replaces require() and lets you override on a per-instance basis, but with a simpler API.

MockDate

This is a very specific utility, one that will only come in handy if you're working with dates/times and need to have control over the time exposed to your code. It's quite simple to use—you just need to call require('mockdate').set(date) and whenever you call new Date(), you'll get that date. One important caveat is that you can't change the timezone, though—Node.js doesn't let you do that easily (until version 13).

redis-mock

This is an even more specific package—it's a mock of node-redis. The idea is to give you a fake datastore so that your code continues to think it's talking to a live Redis server, but it's really talking to an in-memory object managed by redis-mock.
I used it (in combination with mock-require) in my Twitter video downloader bot, @this_vid to fake the bot's datastore. The cache can be easily reset for each test by flushing it like you would a real cache in a (beforeEach/afterEach hook)

I love most of these tools because of how "drop-in" they are, allowing me to "pretend" to use the actual objects . Many of them may not conform to some strict ideas about testing and mocking, but I like them because they're simple and allow me to focus on testing my application logic rather than setting up some unnecessarily complicated architecture.

Posted on by:

shalvah profile

Shalvah

@shalvah

Writer and builder. APIs, dev tools, automation. Advocate of simple design.

Discussion

markdown guide
 

nice collection, if I am allowed to add something; I would add this library called wtfnode: npmjs.com/package/wtfnode .
This comes handy when you are frustrated about some memory leak due to probably some un-handled promises rejections etc.