All Projects → grug → Data Mocks

grug / Data Mocks

Licence: mit
Library to mock local data requests using Fetch or XHR

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Data Mocks

testza
Full-featured test framework for Go! Assertions, fuzzing, input testing, output capturing, and much more! 🍕
Stars: ✭ 409 (+643.64%)
Mutual labels:  unit-testing, test-framework
Wasmite
Now WebAssembly has proper testing, unit-testing and debugging 🤗
Stars: ✭ 20 (-63.64%)
Mutual labels:  unit-testing, test-framework
eat
Json based scenario testing tool(which can have test for functional and non-functional)
Stars: ✭ 41 (-25.45%)
Mutual labels:  unit-testing, test-framework
Zunit
A powerful testing framework for ZSH projects
Stars: ✭ 140 (+154.55%)
Mutual labels:  unit-testing, test-framework
tropic
🍍 Test Runner Library
Stars: ✭ 29 (-47.27%)
Mutual labels:  unit-testing, test-framework
Truth
Fluent assertions for Java and Android
Stars: ✭ 2,359 (+4189.09%)
Mutual labels:  unit-testing, test-framework
oletus
Minimal ECMAScript Module test runner
Stars: ✭ 43 (-21.82%)
Mutual labels:  unit-testing, test-framework
kmtest
Kernel-mode C++ unit testing framework in BDD-style
Stars: ✭ 42 (-23.64%)
Mutual labels:  unit-testing, test-framework
cpptest
🛠️ Powerful, yet simple, C++ unit testing framework; new home after https://sourceforge.net/projects/cpptest/
Stars: ✭ 51 (-7.27%)
Mutual labels:  unit-testing, test-framework
specdris
A test framework for Idris
Stars: ✭ 55 (+0%)
Mutual labels:  unit-testing, test-framework
Atoum
The modern, simple and intuitive PHP unit testing framework.
Stars: ✭ 1,382 (+2412.73%)
Mutual labels:  unit-testing, test-framework
Ava
Node.js test runner that lets you develop with confidence 🚀
Stars: ✭ 19,458 (+35278.18%)
Mutual labels:  unit-testing, test-framework
Tcunit
An unit testing framework for Beckhoff's TwinCAT 3
Stars: ✭ 74 (+34.55%)
Mutual labels:  unit-testing, test-framework
tau
A Micro (1k lines of code) Unit Test Framework for C/C++
Stars: ✭ 121 (+120%)
Mutual labels:  unit-testing, test-framework
Qtools
QTools collection of open source tools for embedded systems development on Windows, Linux and MacOS
Stars: ✭ 64 (+16.36%)
Mutual labels:  unit-testing, test-framework
TcUnit-Runner
Program that makes it possible to automate runs of TcUnit unit tests
Stars: ✭ 23 (-58.18%)
Mutual labels:  unit-testing, test-framework
Dredd
Language-agnostic HTTP API Testing Tool
Stars: ✭ 3,770 (+6754.55%)
Mutual labels:  unit-testing, test-framework
Bash unit
bash unit testing enterprise edition framework for professionals
Stars: ✭ 419 (+661.82%)
Mutual labels:  unit-testing, test-framework
Persimmon
A unit test framework for F# using computation expressions.
Stars: ✭ 37 (-32.73%)
Mutual labels:  unit-testing
Calcite Bootstrap
A Calcite theme and a custom build system for building Bootstrap apps.
Stars: ✭ 49 (-10.91%)
Mutual labels:  web-development

data-mocks

GitHub license npm

Library (written in TypeScript) to mock REST and GraphQL requests

Why is this library useful

When developing web applications locally, it is not uncommon to request data from an API. However, the API might not actually exist yet, or we might want to control what the responses are.

Typically, this sort of problem has been solved by either writing a separate mock API service alongside the project (i.e. having a Node service running locally with your application) or creating a development database that replicates staging or production environments. Both of these approaches are heavy and can lead to using incorrect data if schemas are out of sync.

This library aims to allow rapid local development without the dependency of a database or fully implemented APIs.

Setup

  • Either npm install data-mocks or yarn add data-mocks
  • Optional: extract the scenario from URL using the imported extractScenarioFromLocation() function
    • Or you can just hardcode a string to pass through instead
  • Import injectMocks() function into your project with import { injectMocks } from 'data-mocks'
  • Create an array of Scenario's you would like to use (see examples)
  • Pass array of Scenario's to injectMocks()
  • Hooray, all HTTP requests to mocked endpoints will now respond with the mocked data you have specified

Integration patterns

Regardless of framework or CLI tool used to generate your project, integrating data-mocks into your project is easy. Here are how it may look for you:

React

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

async function main() {
  if (process.env.NODE_ENV === 'development') {
    const { injectMocks, extractScenarioFromLocation } = await import(
      'data-mocks'
    );

    // You could just define your mocks inline if you didn't want to import them.
    const { getMocks } = await import('./path/to/your/mock/definitions');

    injectMocks(getMocks(), extractScenarioFromLocation(window.location));
  }

  ReactDOM.render(<App />, document.getElementById('root'));
}

main();

Angular

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

async function setupMocks() {
    const { injectMocks, extractScenarioFromLocation } = await import(
      'data-mocks'
    );
    // You could just define your mocks inline if you didn't want to import them.
    const { getMocks } = await import('./path/to/your/mock/definitions');

    injectMocks(getMocks(), extractScenarioFromLocation(window.location));
}

async function main() {
  if (environment.production) {
    enableProdMode();
  }

  if (!environment.production) {
    await setupMocks();
  }

  platformBrowserDynamic()
    .bootstrapModule(AppModule)
    .catch((err) => console.error(err));
}

main();

No framework (just vanilla JS)

async function main() {
  if (process.env.NODE_ENV === 'development') {
    const { injectMocks, extractScenarioFromLocation } = await import(
      'data-mocks'
    );

    // You could just define your mocks inline if you didn't want to import them.
    const { getMocks } = await import('./path/to/your/mock/definitions');

    injectMocks(getMocks(), extractScenarioFromLocation(window.location));
  }
}

main();

In these examples, we dynamically import data-mocks and our mock definitions as to not increase production bundle sizes (given that we will never need/want to use these files in production environments).

It is not a requirement to dynamically import data-mocks or your mock definitions - it is just a recommendation :)

REST + GraphQL

data-mocks works with either REST or GraphQL requests. It is also possible to easily mock both in the same application.

See the examples below to see how this is done.

Examples

Basic mock injection without scenarios

import { injectMocks } from 'data-mocks';
import axios from 'axios';

const scenarios = {
  default: [
    {
      url: /login/,
      method: 'POST',
      response: { some: 'good response' },
      responseCode: 200,
    },
    {
      url: /some-other-endpoint/,
      method: 'GET',
      response: { another: 'response' },
      responseCode: 200,
      delay: 1000,
    },
    {
      url: /endpoint-with-headers/,
      method: 'GET',
      response: { same: 'response' },
      responseHeaders: { token: 'mock-token' },
      responseCode: 200,
    },
  ],
};

injectMocks(scenarios);

fetch('http://foo.com/login', { method: 'POST', body: {} })
  .then((response) => response.json())
  .then((myJson) => console.log(myJson)); // resolves with { some: 'good response' } after a 200ms delay

fetch('http://foo.com/some-other-endpoint')
  .then((response) => response.json())
  .then((myJson) => console.log(myJson)); // resolves with { another: 'response' } after a 1 second delay

axios
  .post('http://foo.com/login', {})
  .then((response) => console.log(response)); // resolves with { another: 'response' } after a 200ms delay

axios
  .get('http://foo.com/some-other-endpoint')
  .then((response) => console.log(response)); // resolves with { another: 'response' } after a 1 second delay

In this example, we define a default scenario in our scenarios map. The Scenario objects are described by the Scenario interface. We then inject the scenarios into our application via the injectMocks() function. Finally, when we use fetch / XHR to make a request to endpoints that match our scenario objects, the mocked responses are returned.

N.B

In the above example we are using axios as our XHR library of choice. However data-mocks will work with any library that uses XMLHttpRequest under the hood.


Mock injection with scenarios

import { injectMocks, extractScenarioFromLocation } from 'data-mocks';
import axios from 'axios';

const scenarios = {
  default: [
    {
      url: /login/,
      method: 'POST',
      response: { some: 'good response' },
      responseCode: 200,
    },
    {
      url: /some-other-endpoint/,
      method: 'GET',
      response: { another: 'response' },
      responseCode: 200,
      delay: 1000,
    },
  ],
  failedLogin: [
    {
      url: /login/,
      method: 'POST',
      response: { some: 'bad things happened' },
      responseCode: 401,
    },
  ],
};

injectMocks(scenarios, 'failedLogin');

fetch('http://foo.com/login', { method: 'POST', body: {} }).then((response) =>
  console.log(response)
); // resolves with a 401 after a 200ms delay

fetch('http://foo.com/some-other-endpoint').then((response) =>
  console.log(response)
); // resolves with { another: 'response' } after a 1 second delay

axios
  .post('http://foo.com/login', {})
  .then((response) => console.log(response)); // resolves with a 401 after a 200ms delay

axios
  .get('http://foo.com/some-other-endpoint')
  .then((response) => console.log(response)); // resolves with { another: 'response' } after a 1 second delay

In this example, if we load our site up with ?scenario=failedLogin in the querystring and then attempt to hit the login endpoint, it will fail with a 401. However, the some-other-endpoint endpoint will still respond with the response in the default scenario as we have not provided one in the failedLogin scenario.

Basic GraphQL mock injection

Here, we have a React application using urql as a GraphQL client. This shows how GraphQL queries work and it can be assumed that if you want to use REST mocks in this application, you can do so as you normally would (see examples above).

In reality, the mock definitions would live at a higher level (like the entrypoint into the application) where they could be injected only if we were in development mode.

import React from 'react';
import { injectMocks, extractScenarioFromLocation } from 'data-mocks';
import gql from 'graphql-tag';

const mocks = {
  default: [
    {
      url: /graphql/,
      method: 'GRAPHQL',
      operations: [
        {
          operationName: 'Query',
          type: 'query',
          response: { data: { test: 'test' } },
        },
        {
          operationName: 'Mutation',
          type: 'mutation',
          response: { data: { test: 'test' } },
        },
      ],
    },
  ],
};

injectMocks(mocks, extractScenarioFromLocation(window.location));

const Component = () => {
  const [result] = useQuery({ query: Query }); // result will be { data: { test: 'test' } }

  return <>{result.data.test}</>;
};

Exported types

Scenarios

Property Type Required Description
default Mock[] The default scenario mapping. Provides a default set of mocked responses.
[scenario] Mock[] Additional scenario mappings. The key is the name of the scenario and is what is used in the URL.

HttpMock

Property Type Required Description
url RegExp Regular expression that matches part of the URL.
method string HTTP method matching one of 'GET', 'POST', 'PUT', 'PATCH', 'DELETE'.
response object | string Body of the response.
responseCode number Response code. Defaults to 200.
responseHeaders object Response headers. Defaults to empty.
delay number Delay (in milliseconds) before response is returned. Defaults to 0.

GraphQLMock

Property Type Required Description
url RegExp Regular expression that matches part of the URL.
method string Must be 'GRAPHQL' to specify that this is a GraphQL mock.
operations Array<Operation> Array of GraphQL operations for this request.

Mock

Union type of HttpMock and GraphQLMock.

Operation

Property Type Required Description
type string GraphQL operation type. Must be either query or mutation.
operationName string GraphQL operation name.
response object Body of the response.
responseCode number Response code. Defaults to 200.
responseHeaders object Response headers. Defaults to empty.
delay number Delay (in milliseconds) before response is returned. Defaults to 0.

MockConfig

Property Type Required Description
allowXHRPassthrough boolean Any unmatched routes for XHR will pass through to the actual endpoint, rather than be mocked. Defaults to false.
allowFetchPassthrough boolean Any unmatched routes for fetch will pass through to the actual endpoint, rather than be mocked. Defaults to false.
disableConsoleWarningsForFetch boolean When enabled, this will suppress any console warnings generated by fetch-mock fallbacks

Exported functions

injectMocks

Parameter Type Required Description
scenarios Scenarios[] A mapping of scenarios and their responses
scenario keyof Scenarios[] The scenario to run. Defaults to default
config MockConfig Config object that allows for different behaviour of how mocks are injected

extractScenarioFromLocation

Parameter Type Required Description
location Location The browser location object. The value for the scenario part of the querystring will be extracted and returned

Gotchas

  • GraphQL operations must have an operation name.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].