Skip to content

Commit 1170ad5

Browse files
committed
fix(MongoMemoryServer::getStartOptions): use "forceSamePort", even when instance is not defined
fixes #578
1 parent fb50ae0 commit 1170ad5

File tree

2 files changed

+63
-4
lines changed

2 files changed

+63
-4
lines changed

packages/mongodb-memory-server-core/src/MongoMemoryServer.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -326,17 +326,27 @@ export class MongoMemoryServer extends EventEmitter implements ManagerAdvanced {
326326
/**
327327
* Construct Instance Starting Options
328328
*/
329-
protected async getStartOptions(): Promise<MongoMemoryServerGetStartOptions> {
330-
this.debug('getStartOptions');
329+
protected async getStartOptions(
330+
forceSamePort: boolean = false
331+
): Promise<MongoMemoryServerGetStartOptions> {
332+
this.debug(`getStartOptions: forceSamePort: ${forceSamePort}`);
331333
/** Shortcut to this.opts.instance */
332334
const instOpts = this.opts.instance ?? {};
333335
/**
334336
* This variable is used for determining if "createAuth" should be run
335337
*/
336338
let isNew: boolean = true;
337339

340+
// use pre-defined port if available, otherwise generate a new port
341+
let port = typeof instOpts.port === 'number' ? instOpts.port : undefined;
342+
343+
// if "forceSamePort" is not true, and get a available port
344+
if (!forceSamePort || isNullOrUndefined(port)) {
345+
port = await this.getNewPort(port);
346+
}
347+
338348
const data: StartupInstanceData = {
339-
port: await this.getNewPort(instOpts.port),
349+
port: port,
340350
dbName: generateDbName(instOpts.dbName),
341351
ip: instOpts.ip ?? '127.0.0.1',
342352
storageEngine: instOpts.storageEngine ?? 'ephemeralForTest',
@@ -412,7 +422,7 @@ export class MongoMemoryServer extends EventEmitter implements ManagerAdvanced {
412422
return;
413423
}
414424

415-
const { mongodOptions, createAuth, data } = await this.getStartOptions();
425+
const { mongodOptions, createAuth, data } = await this.getStartOptions(forceSamePort);
416426
this.debug(`_startUpInstance: Creating new MongoDB instance with options:`, mongodOptions);
417427

418428
const instance = await MongoInstance.create(mongodOptions);
@@ -473,6 +483,7 @@ export class MongoMemoryServer extends EventEmitter implements ManagerAdvanced {
473483
}
474484

475485
// assert here, otherwise typescript is not happy
486+
// TODO: remove check, typescript does not need this anymore
476487
assertion(
477488
!isNullOrUndefined(this._instanceInfo.instance),
478489
new Error('"instanceInfo.instance" is undefined!')

packages/mongodb-memory-server-core/src/__tests__/MongoMemoryServer.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,54 @@ describe('MongoMemoryServer', () => {
679679
expect(readdirSpy).toHaveBeenCalledTimes(1);
680680
expect(options.createAuth).toEqual(false);
681681
});
682+
683+
it('should generate a port when no suggestion is defined', async () => {
684+
const mongoServer = new MongoMemoryServer();
685+
const newPortSpy = jest
686+
// @ts-expect-error "getNewPort" is protected
687+
.spyOn(mongoServer, 'getNewPort')
688+
// @ts-expect-error it somehow gets a wrong function type
689+
.mockImplementation((port) => Promise.resolve(port ? port : 2000));
690+
691+
// @ts-expect-error "getStartOptions" is protected
692+
const options = await mongoServer.getStartOptions();
693+
694+
expect(newPortSpy).toHaveBeenCalledTimes(1);
695+
expect(typeof options.data.port === 'number').toBeTruthy();
696+
});
697+
698+
it('should use a predefined port as a suggestion for a port', async () => {
699+
const predefinedPort = 10000;
700+
701+
const mongoServer = new MongoMemoryServer({ instance: { port: predefinedPort } });
702+
const newPortSpy = jest
703+
// @ts-expect-error "getNewPort" is protected
704+
.spyOn(mongoServer, 'getNewPort')
705+
// @ts-expect-error it somehow gets a wrong function type
706+
.mockImplementation((port) => Promise.resolve(port ? port : 2000));
707+
708+
// @ts-expect-error "getStartOptions" is protected
709+
const options = await mongoServer.getStartOptions();
710+
711+
expect(newPortSpy).toHaveBeenCalledWith(predefinedPort);
712+
expect(options.data.port).toStrictEqual(predefinedPort);
713+
});
714+
715+
it('should use a predefined port for a port with "forceSamePort" on', async () => {
716+
const predefinedPort = 30000;
717+
718+
const mongoServer = new MongoMemoryServer({ instance: { port: predefinedPort } });
719+
const newPortSpy = jest
720+
// @ts-expect-error "getNewPort" is protected
721+
.spyOn(mongoServer, 'getNewPort')
722+
.mockImplementation(() => fail('Expected this function to not be called'));
723+
724+
// @ts-expect-error "getStartOptions" is protected
725+
const options = await mongoServer.getStartOptions(true);
726+
727+
expect(newPortSpy).not.toHaveBeenCalled();
728+
expect(options.data.port).toStrictEqual(predefinedPort);
729+
});
682730
});
683731

684732
it('"getDbPath" should return the dbPath', async () => {

0 commit comments

Comments
 (0)