npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

stubborn-server

v2.0.1

Published

NodeJS Stub server for test and dev purposes

Downloads

853

Readme

stubborn-server

Greenkeeper badge Build Status License

NodeJS Stub server for test and dev purposes

Is your backend stubborn?

Features

  • Mocking with static json
  • Mocking with dynamic request handlers based on Express requests
  • Storing/accessing a memory database
  • Separate database per namespace
  • Reset a db at anytime with default values
  • Usage of aliases to get alternate mock responses (allow scenarios flexibility)
  • Integrates well with any test framework

Just show me code!

Ok... create a stubborn.js file where you want to use it content might look like

module.exports = {
  logMode: 'all', // can be 'all', 'info', 'mock', 'warn', 'error' or 'none'
  namespace: '', // help switching between different senarios
  pathToMocks: 'mock-examples', // mock folder relative path
  servePort: 8059,
  includes: ['__custom/express_handlers'], // List of files into the mock folder where the express app will be exposed for custom handling
  fallbacks: [
    { // using "path" key tells that we refer to a local file
      url: '/assets/*',
      path: '/path/to/static/folder'
    },
    { // using "target" key tells that we refer to an http location and is treated as a server proxy
      url: '/*':,
      target: 'localhost:3000'
    },
    { // using "mock" key tells that we refer to an existing mock, a direct regex can be used here
      url: /api\/path\/([^\/]+)/,
      mock: 'api/path/__wildcard__/more/paths'
    }
  ]
};

or a stubborn.json file

{
  "logMode": "mock",
  "namespace": "",
  "pathToMocks": "mock-examples",
  "servePort": 8059,
  "includes": ["__custom/express_handlers"],
  "fallbacks": [
    {
      "url": "/assets/*",
      "path": "/path/to/static/folder"
    },
    {
      "url": "/*",
      "target": "localhost:3000"
    },
    {
      "url": "api\/path\/([^\/]+)",
      "target": "api/path/__wildcard__/more/paths"
    }
  ]
}

Then write your initiator like the one given in demo.js or in tests/...

Might look like this :

const stubbornServer = require('stubborn-server');
const stub = stubbornServer();

stub.start(/* config to extend ./stubborn.js if required */);

// from this point, you may run your queries

stub.config.set({
  namespace: 'alt'
});

// from this point, you may run other queries

stub.stop();

I also have the intention of having this available directly from the command line.

Write your mocks

Mocks can be specified in three ways:

  1. Attaching express handlers
  2. Including express handlers
  3. Configuration-driven

The way you choose depends on the needs of your project. You may also mix and match as the options are not exclusive.

Attaching express handlers

When creating your mock server, a reference to the underlying raw express app is available. You can attach any response handlers you want:

const stubbornServer = require('stubborn-server');
const stub = stubbornServer();

// Attaching express handlers directly via `app` raw reference.
stub.app.use('/my/url/path', (req, res) => {
  // req / res are from express
  console.log(req.method);
  const response = {'hello': 'world'};
  // stub is stubborn server object
  console.log(stub.config.get());
  res.json(response);
});

stub.start();
// from this point, you may run your queries
stub.stop();

Including express handlers

Instead of manually attaching handlers to the app, you may specify paths to express handlers. The handlers will then be require()ed for you.

This example is functionally equivalent to the example above:

main.js:

const stubbornServer = require('stubborn-server');
const stub = stubbornServer();

stub.config.set({
  includes: ['path/to/handler.js'],
});

stub.start();
// from this point, you may run your queries
stub.stop();

handler.js:

module.exports = (app, stub) => {
  app.use('/my/url/path', (req, res) => {
    // req / res are from express
    console.log(req.method);
    const response = {'hello': 'world'};
    // stub is stubborn server instance
    console.log(stub.config.get());
    res.json(response);
  });
};

Configuration-driven

By default, when the server recieves a request it will look into the directory specified by the pathToMocks configuration option for a mock response.

The file name serving as a mock must match the request path plus the request method.

For example, a POST request to http://localhost:3000/api/service will try to find files at the following locations:

  • /path/to/mocks/api/service/post.js
  • /path/to/mocks/api/service/post.json
  • /path/to/mocks/api/service/post/index.js
  • /path/to/mocks/api/service/post/index.json

Basically, it's a require.resolve that finds the proper mock response files.

The following is an example of a basic configuration driven post.js mock:

// this function is the handler being called
module.exports = (req, res, stub) => {
  // req / res are from express
  console.log(req.method); // POST
  // stub is stubborn server object
  console.log(stub.config.get());
  res.json({ 'hello': 'world' });
};

and a post.json mock that returns the same mock response data:

{
  "hello": "world"
}

Plugins

A plugin architecture allows you to extend even more the custom functionality of your server.

Custom loaders

Add your own custom loader that takes precedence over the default behavior of file system lookup and the fallbacks property - this way even if your loader throws you can still rely on the standard functionality.

Here is an example of a custom loader that uses sent data in order to load a mock:

const stubbornServer = require('stubborn-server');
const stub = stubbornServer();

stub.start({
  plugins: [
    {
      loader: (req, { pathToMocks }) => {
        return require(path.join(pathToMocks, req.body.data);
      }
    }
  ]
});

NOTE: you may also define multiple loaders, allowing you to have multiple custom fallbacks systems.

License

GPL-3.0 © 2018 Olivier Rousseau-Guyot