Skip to content

Commit 04b10e6

Browse files
committed
mockContext work
1 parent 7bf4b72 commit 04b10e6

File tree

5 files changed

+41
-12
lines changed

5 files changed

+41
-12
lines changed

src/app/extend/application.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import mergeDescriptors from 'merge-descriptors';
66
import { isAsyncFunction, isObject } from 'is-type-of';
77
import { mock, restore } from 'mm';
88
import { Transport, Logger, LoggerLevel, LoggerMeta } from 'egg-logger';
9-
import { EggCore, EggCoreOptions } from '@eggjs/core';
9+
import { EggCore, EggCoreOptions, ContextDelegation } from '@eggjs/core';
1010
import { getMockAgent, restoreMockAgent } from '../../lib/mock_agent.js';
1111
import {
1212
createMockHttpClient, MockResultFunction,
@@ -38,6 +38,10 @@ export interface MockContextData {
3838
[key: string]: any;
3939
}
4040

41+
export interface MockContextDelegation extends ContextDelegation {
42+
service: any;
43+
}
44+
4145
export default abstract class ApplicationUnittest extends EggCore {
4246
declare options: MockOptions & EggCoreOptions;
4347
_mockHttpClient: MockHttpClientMethod;
@@ -64,7 +68,7 @@ export default abstract class ApplicationUnittest extends EggCore {
6468
* };
6569
* ```
6670
*/
67-
mockContext(data?: MockContextData, options?: MockContextOptions) {
71+
mockContext(data?: MockContextData, options?: MockContextOptions): MockContextDelegation {
6872
data = data ?? {};
6973
function mockRequest(req: IncomingMessage) {
7074
for (const key in data?.headers) {
@@ -93,22 +97,24 @@ export default abstract class ApplicationUnittest extends EggCore {
9397
if (this.currentContext && !this.currentContext[REUSED_CTX]) {
9498
mockRequest(this.currentContext.request.req);
9599
this.currentContext[REUSED_CTX] = true;
96-
return this.currentContext;
100+
return this.currentContext as MockContextDelegation;
97101
}
98102
}
99103
const ctx = this.createContext(req, res);
100104
if (options.mockCtxStorage) {
101105
mock(this.ctxStorage, 'getStore', () => ctx);
102106
}
103-
return ctx;
107+
return ctx as MockContextDelegation;
104108
}
105109

106-
async mockContextScope(fn: () => Promise<any>, data: any) {
110+
async mockContextScope(fn: (ctx?: MockContextDelegation) => Promise<any>, data?: MockContextData) {
107111
const ctx = this.mockContext(data, {
108112
mockCtxStorage: false,
109113
reuseCtxStorage: false,
110114
});
111-
return await this.ctxStorage.run(ctx, fn);
115+
return await this.ctxStorage.run(ctx, async () => {
116+
return await fn(ctx);
117+
});
112118
}
113119

114120
/**

src/lib/app.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,22 @@ export class MockApplication extends Base {
5656
if (this.options.clean !== false) {
5757
const logDir = path.join(this.options.baseDir, 'logs');
5858
try {
59-
if (os.platform() === 'win32') await sleep(1000);
59+
if (os.platform() === 'win32') {
60+
await sleep(1000);
61+
}
6062
await rimraf(logDir);
6163
} catch (err: any) {
6264
console.error(`remove log dir ${logDir} failed: ${err.stack}`);
6365
}
66+
const runDir = path.join(this.options.baseDir, 'run');
67+
try {
68+
if (os.platform() === 'win32') {
69+
await sleep(1000);
70+
}
71+
await rimraf(runDir);
72+
} catch (err: any) {
73+
console.error(`remove run dir ${runDir} failed: ${err.stack}`);
74+
}
6475
}
6576

6677
this.options.clusterPort = await detectPort();

src/lib/mock_custom_loader.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import { debuglog } from 'node:util';
2+
3+
const debug = debuglog('@eggjs/mock/lib/mock_custom_loader');
4+
15
export function setCustomLoader(app: any) {
26
const customLoader = app.config.customLoader;
37
if (!customLoader) return;
@@ -15,6 +19,7 @@ export function setCustomLoader(app: any) {
1519
app.coreLogger.warn('Can\'t override app.%s', appMethodName);
1620
return;
1721
}
22+
debug('[addMethod] %s => %j', appMethodName, loaderConfig);
1823
app[appMethodName] = function(service: any, methodName: string, fn: any) {
1924
if (typeof service === 'string') {
2025
const arr = service.split('.');

test/ctx.test.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ describe('test/ctx.test.ts', () => {
2929
it('should ctx.ip work', () => {
3030
const ctx = app.mockContext();
3131
ctx.request.headers['x-forwarded-for'] = '';
32-
assert(ctx.request.ip === '127.0.0.1');
32+
assert.equal(ctx.request.ip, '127.0.0.1');
3333
});
3434

3535
it('should has services', async () => {
3636
const ctx = app.mockContext();
3737
const data = await ctx.service.foo.get('foo');
38-
assert(data === 'bar');
38+
assert.equal(data, 'bar');
3939
});
4040

4141
it('should not override mockData', async () => {
@@ -57,6 +57,15 @@ describe('test/ctx.test.ts', () => {
5757
assert(nestCtx === currentStore);
5858
});
5959
});
60+
61+
await app.mockContextScope(async () => {
62+
const ctx = app.ctxStorage.getStore();
63+
await app.mockContextScope(async (newCtx: any) => {
64+
const currentStore = app.ctxStorage.getStore();
65+
assert.equal(newCtx, currentStore);
66+
assert.notEqual(ctx, currentStore);
67+
});
68+
});
6069
});
6170

6271
it('should not conflict with concurrent call', async () => {

test/fixtures/demo/app/service/foo.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
'use strict';
2-
31
module.exports = function(app) {
42
class Foo extends app.Service {
5-
* get() {
3+
async get() {
64
return 'bar';
75
}
86

0 commit comments

Comments
 (0)