Gathering detailed insights and metrics for egg-mock
Gathering detailed insights and metrics for egg-mock
Gathering detailed insights and metrics for egg-mock
Gathering detailed insights and metrics for egg-mock
npm install egg-mock
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
145 Stars
279 Commits
31 Forks
26 Watching
11 Branches
39 Contributors
Updated on 12 Jul 2024
JavaScript (98.24%)
TypeScript (1.76%)
Cumulative downloads
Total Downloads
Last day
-4.4%
2,472
Compared to previous day
Last week
-2.8%
17,584
Compared to previous week
Last month
0.7%
78,901
Compared to previous month
Last year
-5.4%
1,016,894
Compared to previous year
17
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.
1$ npm i egg-mock --save-dev
Launch a mock server with mm.app
1// test/index.test.js 2const path = require('path'); 3const mm = require('egg-mock'); 4 5describe('some test', () => { 6 let app; 7 before(() => { 8 app = mm.app({ 9 baseDir: 'apps/foo' 10 }); 11 return app.ready(); 12 }) 13 after(() => app.close()); 14 15 it('should request /', () => { 16 return app.httpRequest() 17 .get('/') 18 .expect(200); 19 }); 20});
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
;
baseDir
is optional that is process.cwd()
by default.
1before(() => { 2 app = mm.app(); 3 return app.ready(); 4});
framework is optional, it's node_modules/egg
by default.
1before(() => { 2 app = mm.app({ 3 baseDir: 'apps/demo', 4 framework: true, 5 }); 6 return app.ready(); 7});
If eggPlugin.name
is defined in package.json
, it's a plugin that will be loaded to plugin list automatically.
1before(() => { 2 app = mm.app({ 3 baseDir: 'apps/demo', 4 }); 5 return app.ready(); 6});
You can also test the plugin in different framework, e.g. test aliyun-egg and framework-b in one plugin.
1describe('aliyun-egg', () => { 2 let app; 3 before(() => { 4 app = mm.app({ 5 baseDir: 'apps/demo', 6 framework: path.join(__dirname, 'node_modules/aliyun-egg'), 7 }); 8 return app.ready(); 9 }); 10}); 11 12describe('framework-b', () => { 13 let app; 14 before(() => { 15 app = mm.app({ 16 baseDir: 'apps/demo', 17 framework: path.join(__dirname, 'node_modules/framework-b'), 18 }); 19 return app.ready(); 20 }); 21});
If it's detected as an plugin, but you don't want it to be, you can use plugin = false
.
1before(() => { 2 app = mm.app({ 3 baseDir: 'apps/demo', 4 plugin: false, 5 }); 6 return app.ready(); 7});
Create a mock application.
Create a mock cluster server, but you can't use API in application, you should test using supertest
.
1const mm = require('egg-mock'); 2describe('test/app.js', () => { 3 let app, config; 4 before(() => { 5 app = mm.cluster(); 6 return app.ready(); 7 }); 8 after(() => app.close()); 9 10 it('some test', () => { 11 return app.httpRequest() 12 .get('/config') 13 .expect(200) 14 }); 15});
You can disable coverage, because it's slow.
1mm.cluster({ 2 coverage: false, 3});
Mock env when starting
1// production environment 2mm.env('prod'); 3mm.app({ 4 cache: false, 5});
Environment list https://github.com/eggjs/egg-core/blob/master/lib/loader/egg_loader.js#L82
Mock level that print to stdout/stderr
1// DON'T log to terminal 2mm.consoleLevel('NONE');
level list: DEBUG
, INFO
, WARN
, ERROR
, NONE
mock home directory
restore all mock data, e.g. afterEach(mm.restore)
Options for mm.app
and mm.cluster
The directory of application, default is process.cwd()
.
1mm.app({ 2 baseDir: path.join(__dirname, 'fixtures/apps/demo'), 3})
You can use a string based on $CWD/test/fixtures
for short
1mm.app({ 2 baseDir: 'apps/demo', 3})
The directory of framework
1mm.app({ 2 baseDir: 'apps/demo', 3 framework: path.join(__dirname, 'fixtures/egg'), 4})
It can be true when test an framework
The directory of plugin, it's detected automatically.
1mm.app({ 2 baseDir: 'apps/demo', 3})
Define a list of plugins
Determine whether enable cache. it's cached by baseDir.
Clean all logs directory, default is true.
If you are using ava
, disable it.
Assert some string value in the logger instance.
It is recommended to pair app.mockLog()
with app.expectLog()
or app.notExpectLog()
.
Using app.expectLog()
or app.notExpectLog()
alone requires dependency on the write speed of the log. When the server disk is high IO, unstable results will occur.
1it('should work', async () => { 2 app.mockLog(); 3 await app.httpRequest() 4 .get('/') 5 .expect('hello world') 6 .expect(200); 7 8 app.expectLog('foo in logger'); 9 app.expectLog('foo in coreLogger', 'coreLogger'); 10 app.expectLog('foo in myCustomLogger', 'myCustomLogger'); 11 12 app.notExpectLog('bar in logger'); 13 app.notExpectLog('bar in coreLogger', 'coreLogger'); 14 app.notExpectLog('bar in myCustomLogger', 'myCustomLogger'); 15});
Request current app http server.
1it('should work', () => { 2 return app.httpRequest() 3 .get('/') 4 .expect('hello world') 5 .expect(200); 6});
See supertest to get more APIs.
Assert current response not contains the specified header
1it('should work', () => { 2 return app.httpRequest() 3 .get('/') 4 .unexpectHeader('set-cookie') 5 .expect(200); 6});
Assert current response contains the specified header
1it('should work', () => { 2 return app.httpRequest() 3 .get('/') 4 .expectHeader('set-cookie') 5 .expect(200); 6});
1const ctx = app.mockContext({ 2 user: { 3 name: 'Jason' 4 } 5}); 6console.log(ctx.user.name); // Jason
1await app.mockContextScope(async ctx => {
2 console.log(ctx.user.name); // Jason
3}, {
4 user: {
5 name: 'Jason'
6 }
7});
1app.mockCookies({ 2 foo: 'bar' 3}); 4const ctx = app.mockContext(); 5console.log(ctx.getCookie('foo'));
Mock request header
1app.mockSession({ 2 foo: 'bar' 3}); 4const ctx = app.mockContext(); 5console.log(ctx.session.foo);
1it('should mock user name', function* () { 2 app.mockService('user', 'getName', function* (ctx, methodName, args) { 3 return 'popomore'; 4 }); 5 const ctx = app.mockContext(); 6 yield ctx.service.user.getName(); 7});
You can mock an error for service
1app.mockServiceError('user', 'home', new Error('mock error'));
1app.mockCsrf(); 2 3return app.httpRequest() 4 .post('/login') 5 .expect(302);
Mock httpclient request, e.g.: ctx.curl
1app.get('/', function*() { 2 const ret = yield this.curl('https://eggjs.org'); 3 this.body = ret.data.toString(); 4}); 5 6app.mockHttpclient('https://eggjs.org', { 7 // can be buffer / string / json / function 8 // will auto convert to buffer 9 // follow options.dataType to convert 10 data: 'mock egg', 11}); 12// app.mockHttpclient('https://eggjs.org', 'get', mockResponse); // mock get 13// app.mockHttpclient('https://eggjs.org', [ 'get' , 'head' ], mockResponse); // mock get and head 14// app.mockHttpclient('https://eggjs.org', '*', mockResponse); // mock all methods 15// app.mockHttpclient('https://eggjs.org', mockResponse); // mock all methods by default 16// app.mockHttpclient('https://eggjs.org', 'get', function(url, opt) { return 'xxx' }); // support fn 17 18return app.httpRequest() 19 .post('/') 20 .expect('mock egg');
You can also use Regular Expression for matching url.
1app.mockHttpclient(/\/users\/[a-z]$/i, {
2 data: {
3 name: 'egg',
4 },
5});
You can alse mock agent.httpclient
1app.agent.mockHttpclient('https://eggjs.org', {
2 data: {
3 name: 'egg',
4 },
5});
We also provide a bootstrap file for applications' unit test to reduce duplicated code:
1const { app, mock, assert } = require('egg-mock/bootstrap'); 2 3describe('test app', () => { 4 it('should request success', () => { 5 // mock data will be restored each case 6 mock.data(app, 'method', { foo: 'bar' }); 7 return app.httpRequest() 8 .get('/foo') 9 .expect(res => { 10 assert(!res.headers.foo); 11 }) 12 .expect(/bar/); 13 }); 14}); 15 16describe('test ctx', () => { 17 it('can use ctx', async function() { 18 const res = await this.ctx.service.foo(); 19 assert(res === 'foo'); 20 }); 21});
We inject ctx to every test case, so you can use app.currentContext
in your test case.
and the first call of app.mockContext
will reuse app.currentContext
.
1const { app, mock, assert } = require('egg-mock/bootstrap'); 2 3describe('test ctx', () => { 4 it('should can use ctx', () => { 5 const ctx = app.currentContext; 6 assert(ctx); 7 }); 8 9 it('should reuse ctx', () => { 10 const ctx = app.currentContext; 11 // first call will reuse app.currentContext 12 const mockCtx = app.mockContext(); 13 assert(ctx === mockCtx); 14 // next call will create a new context 15 // multi call app.mockContext will get wrong context with app.currentContext 16 // so we recommend to use app.mockContextScope 17 const mockCtx2 = app.mockContext(); 18 assert(ctx !== mockCtx); 19 }); 20});
And if you use mm.app to bootstrap app, you can manually call setGetAppCallback, then egg-mock will inject ctx for each test case.
1// test/.setup.js 2const mm = require('egg-mock'); 3const path = require('path'); 4before(async function() { 5 const app = this.app = mm.app(); 6 mm.setGetAppCallback(() => { 7 return app; 8 }); 9 await app.ready(); 10}); 11 12 13// test/index.test.js 14it('should work', function() { 15 // eslint-disable-next-line no-undef 16 assert(this.app.currentContext); 17});
EGG_BASE_DIR: the base dir of egg app EGG_FRAMEWORK: the framework of egg app
Please open an issue here.
Made with contributors-img.
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
0 existing vulnerabilities detected
Reason
Found 7/30 approved changesets -- score normalized to 2
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
Reason
security policy file not detected
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More