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

import-inject-loader

v0.2.4

Published

This webpack loader allows you to overwrite dependencies by own implementations for testing purposes.

Downloads

52

Readme

Build Status

Overwrite your dependencies with mocks and custom implementations.

Description

import-inject-loader is a webpack loader which allows you to replace imported dependencies and global variables by custom implementations. At build time new exported functions are added to your module which makes it possible to change implementations at run time (e.g. within tests).

Usage

Imagine we have this module and want to mock fetch in our unit test:

export const getUsers = async () => {
  const response = await fetch('https://jsonplaceholder.typicode.com/users');
  return response.json();
};

We can do it like this:

import expect from 'expect';
import {
  getUsers,
  ilOverwriteFetch,
  ilResetAll
} from 'import-inject-loader?fetch!../src/get-users';

define('Test getUsers()', () => {
  it('should return users', async () => {
    // mock `fetch`
    ilOverwriteFetch((url) => ({
      json: [
        { name: 'John Doe' }
      ]
    }));

    // test `getUsers`
    const users = await getUsers();
    expect(users).toEqual([
      { name: 'John Doe' }
    ]);
  });

  afterEach(ilResetAll);
});

Explanation

The getUsers function is hard to test, because it requires a network request. With import-inject-loader we can mock fetch to get rid of the network request.

To do so we simply import our module with the import-inject-loader and specify the names of imported or global variables we'd like to replace in a comma separated list:

import {
  getUsers,
  ilOverwriteFetch,
  ilResetAll
} from 'import-inject-loader?fetch!../src/get-users';

You can see that two new functions are exported from ../src/get-users: ilOverwriteFetch and ilResetAll.

ilOverwriteFetch is exported, because we passed ?fetch to the import-inject-loader. If we would pass ?fetch,Math,localStorage the function ilOverwriteFetch, ilOverwriteMath and ilOverwriteLocalStorage would be exported (assuming all three variables are actually used in the file). If you pass ?fatch - which is a typo - an error is thrown, because no fatch is used inside ../src/get-users. The ilOverwrite{Name} functions allow you to swap out imported or global variables with own implementations.

The ilResetAll is always exported. It is a handy way to reset your custom implementations with the original implementation after your test is done.

Note that you only change the implementation of fetch within this one module. Other modules aren't affect and the global fetch on window isn't changed.

The import-inject-loader basically rewrites your module to something like this (not exactly, but you get the point):

let fetch = window.fetch;

export const ilOverwriteFetch = (newFetch) => fetch = newFetch;
export const ilResetAll = () => fetch = window.fetch;

export const getUsers = async () => {
  const response = await fetch('https://jsonplaceholder.typicode.com/users');
  return response.json();
};

As explained this functionallity is not limited to global variables. You can also mock imported variables. Say you have another module which uses our getUsers like this:

import { getUsers } from './get-users';

export countUsers = async () => {
  const users = await getUsers();
  return users.length;
};

We can test countUsers like this:

import {
  countUsers,
  ilOverwriteGetUsers,
  ilResetAll
} from 'import-inject-loader?getUsers!../src/count-users';

define('Test countUsers()', () => {
  it('should return users', async () => {
    // mock `getUsers`
    ilOverwriteGetUsers(() => [
      { name: 'John Doe' }
    ]);

    // test `countUsers`
    const count = await countUsers();
    expect(users).toBe(1);
  });

  afterEach(ilResetAll);
});

Examples

You can check out a standalone example with all source and test files in our examples/ directory.

Another example which uses React, TypeScript and JSX can be found here.