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

@zeromake/egg-mock

v3.24.2

Published

mock server for egg

Downloads

6

Readme

egg-mock

NPM version build status Test coverage David deps Known Vulnerabilities npm download

Mock library for testing Egg applications, plugins and custom Egg frameworks with ease. egg-mock inherits all APIs from node_modules/mm, offering more flexibility.

Install

$ npm i egg-mock --save-dev

Usage

Create testcase

Launch a mock server with mm.app

// test/index.test.js
const path = require('path');
const mm = require('egg-mock');

describe('some test', () => {
  let app;
  before(() => {
    app = mm.app({
      baseDir: 'apps/foo'
    });
    return app.ready();
  })
  after(() => app.close());

  it('should request /', () => {
    return app.httpRequest()
      .get('/')
      .expect(200);
  });
});

Retrieve Agent instance through app.agent after mm.app started.

Using mm.cluster launch cluster server, you can use the same API as mm.app;

Test Application

baseDir is optional that is process.cwd() by default.

before(() => {
  app = mm.app();
  return app.ready();
});

Test Framework

framework is optional, it's node_modules/egg by default.

before(() => {
  app = mm.app({
    baseDir: 'apps/demo',
    framework: true,
  });
  return app.ready();
});

Test Plugin

If eggPlugin.name is defined in package.json, it's a plugin that will be loaded to plugin list automatically.

before(() => {
  app = mm.app({
    baseDir: 'apps/demo',
  });
  return app.ready();
});

You can also test the plugin in different framework, e.g. test aliyun-egg and framework-b in one plugin.

describe('aliyun-egg', () => {
  let app;
  before(() => {
    app = mm.app({
      baseDir: 'apps/demo',
      framework: path.join(__dirname, 'node_modules/aliyun-egg'),
    });
    return app.ready();
  });
});

describe('framework-b', () => {
  let app;
  before(() => {
    app = mm.app({
      baseDir: 'apps/demo',
      framework: path.join(__dirname, 'node_modules/framework-b'),
    });
    return app.ready();
  });
});

If it's detected as an plugin, but you don't want it to be, you can use plugin = false.

before(() => {
  app = mm.app({
    baseDir: 'apps/demo',
    plugin: false,
  });
  return app.ready();
});

API

mm.app(options)

Create a mock application.

mm.cluster(options)

Create a mock cluster server, but you can't use API in application, you should test using supertest.

const mm = require('egg-mock');
describe('test/app.js', () => {
  let app, config;
  before(() => {
    app = mm.cluster();
    return app.ready();
  });
  after(() => app.close());

  it('some test', () => {
    return app.httpRequest()
      .get('/config')
      .expect(200)
  });
});

You can disable coverage, because it's slow.

mm.cluster({
  coverage: false,
});

mm.env(env)

Mock env when starting

// production environment
mm.env('prod');
mm.app({
  cache: false,
});

Environment list https://github.com/eggjs/egg-core/blob/master/lib/loader/egg_loader.js#L82

mm.consoleLevel(level)

Mock level that print to stdout/stderr

// DON'T log to terminal
mm.consoleLevel('NONE');

level list: DEBUG, INFO, WARN, ERROR, NONE

mm.home(homePath)

mock home directory

mm.restore()

restore all mock data, e.g. afterEach(mm.restore)

options

Options for mm.app and mm.cluster

baseDir {String}

The directory of application, default is process.cwd().

mm.app({
  baseDir: path.join(__dirname, 'fixtures/apps/demo'),
})

You can use a string based on $CWD/test/fixtures for short

mm.app({
  baseDir: 'apps/demo',
})

framework {String/Boolean}

The directory of framework

mm.app({
  baseDir: 'apps/demo',
  framework: path.join(__dirname, 'fixtures/egg'),
})

It can be true when test an framework

plugin

The directory of plugin, it's detected automatically.

mm.app({
  baseDir: 'apps/demo',
})

plugins {Object}

Define a list of plugins

cache {Boolean}

Determine whether enable cache. it's cached by baseDir.

clean {Boolean}

Clean all logs directory, default is true.

If you are using ava, disable it.

app.mockLog([logger]) and app.expectLog(str[, logger])

Assert some string value in the logger instance. It is recommended to pair app.mockLog() with app.expectLog(). Using app.expectLog() alone requires dependency on the write speed of the log. When the server disk is high IO, unstable results will occur.

it('should work', async () => {
  app.mockLog();
  await app.httpRequest()
    .get('/')
    .expect('hello world')
    .expect(200);

  app.expectLog('foo in logger');
  app.expectLog('foo in coreLogger', 'coreLogger');
  app.expectLog('foo in myCustomLogger', 'myCustomLogger');
});

app.httpRequest()

Request current app http server.

it('should work', () => {
  return app.httpRequest()
    .get('/')
    .expect('hello world')
    .expect(200);
});

See supertest to get more APIs.

app.httpAgent(opt?)

Request current app http server and has session.

router

module.exports = app => {
  app.get('home', '/', function* () {
    this.cookies.set('cookie', 'hey');
    this.body = 'home';
  });

  app.get('session', '/return', function* () {
    const cookie = this.cookies.get('cookie');
    if (cookie) {
      this.body = cookie;
    } else {
      this.body = ':(';
    }
  });
};

test

let agent;
before(() => {
  return app.ready().then(() => {
    // use supertest Agent optional opt param
    agent = app.httpAgent();
  });
});

it('should not cookies', function(done) {
  agent
    .get('/return')
    .expect(':(', done);
});
it('should save cookies', function(done) {
  agent
    .get('/')
    .expectHeader('set-cookie')
    .expect(200, done);
});

it('should send cookies', function(done) {
  agent
    .get('/return')
    .expect('hey', done);
});

See supertest to get more APIs.

.unexpectHeader(name)

Assert current response not contains the specified header

it('should work', () => {
  return app.httpRequest()
    .get('/')
    .unexpectHeader('set-cookie')
    .expect(200);
});

.expectHeader(name)

Assert current response contains the specified header

it('should work', () => {
  return app.httpRequest()
    .get('/')
    .expectHeader('set-cookie')
    .expect(200);
});

app.mockContext(options)

const ctx = app.mockContext({
  user: {
    name: 'Jason'
  }
});
console.log(ctx.user.name); // Jason

app.mockCookies(data)

app.mockCookies({
  foo: 'bar'
});
const ctx = app.mockContext();
console.log(ctx.getCookie('foo'));

app.mockHeaders(data)

Mock request header

app.mockSession(data)

app.mockSession({
  foo: 'bar'
});
const ctx = app.mockContext();
console.log(ctx.session.foo);

app.mockService(service, methodName, fn)

it('should mock user name', function* () {
  app.mockService('user', 'getName', function* (ctx, methodName, args) {
    return 'popomore';
  });
  const ctx = app.mockContext();
  yield ctx.service.user.getName();
});

app.mockServiceError(service, methodName, error)

You can mock an error for service

app.mockServiceError('user', 'home', new Error('mock error'));

app.mockCsrf()

app.mockCsrf();

return app.httpRequest()
  .post('/login')
  .expect(302);

app.mockHttpclient(url, method, data)

Mock httpclient request, e.g.: ctx.curl

app.get('/', function*() {
  const ret = yield this.curl('https://eggjs.org');
  this.body = ret.data.toString();
});

app.mockHttpclient('https://eggjs.org', {
  // can be buffer / string / json / function
  // will auto convert to buffer
  // follow options.dataType to convert
  data: 'mock egg',
});
// app.mockHttpclient('https://eggjs.org', 'get', mockResponse); // mock get
// app.mockHttpclient('https://eggjs.org', [ 'get' , 'head' ], mockResponse); // mock get and head
// app.mockHttpclient('https://eggjs.org', '*', mockResponse); // mock all methods
// app.mockHttpclient('https://eggjs.org', mockResponse); // mock all methods by default
// app.mockHttpclient('https://eggjs.org', 'get', function(url, opt) { return 'xxx' }); // support fn

return app.httpRequest()
  .post('/')
  .expect('mock egg');

You can also use Regular Expression for matching url.

app.mockHttpclient(/\/users\/[a-z]$/i, {
  data: {
    name: 'egg',
  },
});

You can alse mock agent.httpclient

app.agent.mockHttpclient('https://eggjs.org', {
  data: {
    name: 'egg',
  },
});

Bootstrap

We also provide a bootstrap file for applications' unit test to reduce duplicated code:

const { app, mock, assert } = require('egg-mock/bootstrap');

describe('test app', () => {
  it('should request success', () => {
    // mock data will be restored each case
    mock.data(app, 'method', { foo: 'bar' });
    return app.httpRequest()
      .get('/foo')
      .expect(res => {
        assert(!res.headers.foo);
      })
      .expect(/bar/);
  });
});

Questions & Suggestions

Please open an issue here.

License

MIT