mocker-server
Mock server built with real testing needs in mind.
The mocha
or jest
test runner is needed to be used as the MockedServer automatically binds "checkers" to test all assertions were fulfilled during all tests.
The MockedServer uses Koa inside for routing and request handling, so you write Koa-like request handlers.
Installation & Configuration
- run:
npm i mocked-server -D
- place configuration inside your package.json
{
"mocked-server": {
"testRunner": "mocha"
}
}
Valid options for the testRunner
: mocha
/ jest
/ none
.
Example
const { MockServer } = require('mocked-server');
class SomeService extends MockedServer {
constructor () {
this.super(3000);
this.endpoint = this.post('/somePath/:id', (ctx) => {
ctx.body = { message: 'default response' };
ctx.status = 200;
});
}
}
const myServer = new MockedService();
Assume we are testing a testedProcedure
function (or an API) which should call SomeService:
async function testedProcedure (id = 1) {
}
describe('testedProcedure', () => {
it('should call our endpoint', async () => {
myServer.endpoint.handleNext();
await testedProcedure();
});
it('should call our endpoint - with custom handler', async () => {
myServer.endpoint.handleNext((ctx) => {
ctx.body = { message: 'very special message' };
ctx.status = 201;
});
await testedProcedure();
await testedProcedure();
});
it('should call our endpoint - with custom handler', async () => {
myServer.endpoint.handleNext((ctx) => {
ctx.body = { message: 'first response' };
ctx.status = 201;
});
myServer.endpoint.handleNext((ctx) => {
ctx.body = { message: 'second response' };
ctx.status = 201;
});
await testedProcedure();
await testedProcedure();
await testedProcedure();
});
it('should use an authorization', async () => {
myServer.endpoint.handleNext(async (ctx) => {
assert(ctx.get('Authorization'), 'Bearer myToken');
assert.strictEqual(ctx.params.id, 'expected-id-value');
await next();
});
await testedProcedure();
});
it('should not call the endpoint', async () => {
myServer.endpoint.notReceive();
await testedProcedure();
});
it('should call the endpoint', async () => {
const checker = myServer.endpoint.handleNext();
await testedProcedure();
checker();
});
it('should call the endpoint via API', async () => {
const request = require('supertest');
const express = require('express');
const app = express();
app.post('/endpoint-caller', function(req, res, next) {
testedProcedure().then(() => {
res.status(200).json({ name: 'john' });
}, next);
});
await request(app)
.post('/endpoint-caller')
.expect(200)
.expect(myServer.endpoint.handleNext())
});
it('should not call the endpoint', async () => {
setTimeout(() => testedProcedure(), 1000);
await myServer.endpoint.waitForNext();
});
it('should call our endpoint - with custom handler', async () => {
myServer.endpoint
.matching((ctx) => ctx.params.id === '2')
.handleNext((ctx) => {
ctx.body = { message: 'received the id 2!' };
ctx.status = 201;
});
await testedProcedure(1);
await testedProcedure(2);
await testedProcedure(3);
});
it('should call our endpoint - with custom handler', async () => {
myServer.endpoint
.matchingParams({ myPathParam: 'someValue' })
.matchingQuery({ myQueryParam: 1 })
.matchingHeaders({ Authorization: 'token-1' })
.matchingBody({ bodyProperty: 'expectedValue' })
.handleNext((ctx) => {
ctx.body = { message: 'received expected request!' };
ctx.status = 201;
});
await testedProcedure();
});
});