Socket
Book a DemoInstallSign in
Socket

@apparts/backend-test

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@apparts/backend-test

A framework for database-incorborating backend-testing

4.2.1
latest
Source
npmnpm
Version published
Weekly downloads
132
676.47%
Maintainers
1
Weekly downloads
 
Created
Source

#+TITLE: @apparts/backend-test #+DATE: [2021-02-11 Thu] #+AUTHOR: Philipp Uhl

This library supports testing @apparts-based backends that use Postgresql databases provide express based APIs.

  • Usage
  • Add to your =package.json= in the =scripts= section: #+BEGIN_SRC js "testOne": "jest", "test": "jest --watch --detectOpenHandles", "testCoverage": "jest --coverage" #+END_SRC

  • Create a =jest.config.js= file in the root directory of your project. #+BEGIN_SRC js const jestConfig = require("@apparts/backend-test").getJestConfig();

    module.exports = { ...jestConfig, // additional config }; #+END_SRC

  • Create a =config/db-test-config.json= or =config/db-test-config.js= or export the values as an environment variable with the name =DB_TEST_CONFIG= with this content (as JSON, for the js file you'd need to export the object): #+BEGIN_EXAMPLE { "use": "postgresql", "postgresql": { "host": "localhost", "port": 5432, "user": "postgres", "pw": "", "db": "", "maxPoolSize": 1, "connectionTimeoutMillis": 10000, "idleTimeoutMillis": 10000, "bigIntAsNumber": true } } #+END_EXAMPLE

  • Create tests. To use this library, start the tests with this on top: #+BEGIN_SRC js const { app, url, error, getPool } = require("@apparts/backend-test")({ testName: "", // apiContainer: myEndpoint, ...require("./tests/config.js")
    }); #+END_SRC

  • Create a =tests/config.js= for storing test information that is valid for more than one test: #+BEGIN_SRC js const fs = require("fs"); module.exports = { schemas: ["schema-file-name-0001.sql" /, .../] .map(name => fs.readFileSync(name).toString()), apiVersion: 1, }; #+END_SRC

  • Run tests with #+BEGIN_SRC sh npm run test

    for coverage report:

    npm run testCoverage

    without watching file changes:

    npm run testOne #+END_SRC

** Parameters

=require("@apparts/backend-test")= returns a function with the following parameters:

  • =testName : string= :: (Required) The name of this particular test (needs to be unique). Used to create a database for this test to run in
  • =apiVersion : int= :: (Required) The API version of a versioned API, that is being tested
  • =apiContainer: object= :: The container for the functions you want [[https://github.com/phuhl/apparts-types][@apparts/types]] =checkApiTypes= to test against. If this parameter is not supplied, =checkType= and =allChecked= will throw an error.
  • =schemas : [string]= :: Database schemas, to be run first to create all tables
  • =databasePreparations : [async function : string]= :: A list of functions (that can be async) that return strings, containing sql code that should be run to setup the database
  • =testApp : express app= :: If supplied, this app will be used as the express app, the tests will be performed on. Otherwise a default test app will be used.

** Returns

=require("@apparts/backend-test")= returns a function wich returns an object with the following key/value pairs:

  • =checkType : (any, string) => boolean= :: A wrapper around the =checkType= function from the [[https://github.com/phuhl/apparts-types][@apparts/types]] package. The first parameter of =checkType= is already set (with value from =apiContainer= parameter) for convenience.
  • =allChecked : (string) => boolean= :: A wrapper around the ==allChecked= function from the [[https://github.com/phuhl/apparts-types][@apparts/types]] package. The first parameter of =allChecked= is already set (with value from =apiContainer= parameter) for convenience.
  • =app : = :: A express app. It lacks routes, these have to be added manually. A minimal middleware is already applied to this app (injection of database, body parser).
  • =url : (string) => string= :: A helper that turns a string to a versioned version of this string, by prepending =/v//= to the string. =apiVersion= is the value of the parameter =apiVersion=. This allows to change the api-version of all calls with one variable.
  • =error : (string, ?string) => object= :: A helper that creates an object of the form of the body, produced by the =HttpError= from the package [[https://github.com/phuhl/apparts-error][@apparts/error]]. Can be used with the supertest =toMatchObject= matcher.
  • =runDBQuery : async (async () => any) => any= :: A function that expects a function as parameter. This function receives a [[https://github.com/phuhl/apparts-db][@apparts/db]] =DBS= object as parameter. It's return value will be awaited and returned by =runDBQuery=.
  • =getPool : () => = :: Returns a [[https://github.com/phuhl/apparts-db][@apparts/db]] =DBS= object.

** Minimal example

  • =jest.config.js=: #+BEGIN_SRC js const jestConfig = require("@apparts/backend-test").getJestConfig();

    module.exports = { ...jestConfig, // additional config }; #+END_SRC

  • =config/db-test-config.json= as described above

  • Tests with #+BEGIN_SRC js const { app, url } = require("@apparts/backend-test")({ testName: "", apiVersion: 1 });

    test("My test", async () => { // requesting GET "/v/1/test" const response = await request(app).get(url("test")); expect(response.status).toBe(200); }); #+END_SRC

** Full-ish example

#+BEGIN_SRC js const { app, url, checkType, allChecked, error, getPool, } = require("@apparts/backend-test")({ testName: "", apiContainer: require("./myEndpoint"),

// Returns everything that is the same for all endpoints of this
// APIs version: apiVersion, schemas
...require("./tests/config.json") ,

// Insert values for the tests to use.
databasePreparations: [
  // Common setup queries can be stored in a file
  require("./tests/insertUsers.sql.js"),
  // Simple insertations
  () => 'INSERT INTO "myTable" (myCollumn) VALUES (1), (2)';
  // More complicated calculated values
  async () => {
    const hash = await require("bcryptjs").hash("password123", 10);
    return `INSERT INTO "passwords" (password) VALUES (${hash})`;
  };
],

});

const request = require("supertest");

describe("GET test", () => { // Using a variable for the function name makes it easy to copy this // test for another endpoint and not forgot to change the function // name in some places. const functionName = "myEndpoint"; test("Check return code", async () => { // Requesting GET "/v/1/test", using the url function. This makes // it easy to copy this file, edit the tests to reflect api changes // and thus reuse it for the next api version. const response = await request(app).get(url("test")); expect(response.status).toBe(200);

  // Checking against the database
  // const dbs = getPool();
  // await dbs.raw("SELECT ...");
  // expect(...);

  // Throws if not correct, so no expect is needed
  checkType(response, functionName);
});

test("Check error", async () => {
  const response = await request(app).get(url("test/error"));
  expect(response.status).toBe(400);
  expect(response.body).toMatchObject(error("This endpoint fails", "Reason: \"error\""));
  checkType(response, functionName);
});

test(("All possible responses tested") => {
  // Throws if not all checked, so no expect is needed
  allChecked(functionName);
});

}); #+END_SRC

Keywords

apparts

FAQs

Package last updated on 30 Aug 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.