@@ -39,6 +39,33 @@ test('input validation', async (t) => {
3939 } ) ;
4040 } , { code : 'ERR_INVALID_ARG_TYPE' } ) ;
4141 } ) ;
42+
43+ await t . test ( 'throws if exports is not an object' , async ( t ) => {
44+ assert . throws ( ( ) => {
45+ t . mock . module ( __filename , {
46+ exports : null ,
47+ } ) ;
48+ } , { code : 'ERR_INVALID_ARG_TYPE' } ) ;
49+ } ) ;
50+
51+ await t . test ( 'allows exports to be used with legacy options' , async ( t ) => {
52+ const fixturePath = fixtures . path ( 'module-mocking' , 'basic-cjs.js' ) ;
53+ const fixture = pathToFileURL ( fixturePath ) ;
54+
55+ t . mock . module ( fixture , {
56+ exports : { value : 'from exports' } ,
57+ namedExports : { value : 'from namedExports' } ,
58+ defaultExport : { from : 'defaultExport' } ,
59+ } ) ;
60+
61+ const cjsMock = require ( fixturePath ) ;
62+ const esmMock = await import ( fixture ) ;
63+
64+ assert . strictEqual ( cjsMock . value , 'from namedExports' ) ;
65+ assert . strictEqual ( cjsMock . from , 'defaultExport' ) ;
66+ assert . strictEqual ( esmMock . value , 'from namedExports' ) ;
67+ assert . strictEqual ( esmMock . default . from , 'defaultExport' ) ;
68+ } ) ;
4269} ) ;
4370
4471test ( 'core module mocking with namedExports option' , async ( t ) => {
@@ -517,42 +544,33 @@ test('mocks can be restored independently', async (t) => {
517544 assert . strictEqual ( esmImpl . fn , undefined ) ;
518545} ) ;
519546
520- test ( 'core module mocks can be used by both module systems' , async ( t ) => {
521- const coreMock = t . mock . module ( 'readline' , {
522- namedExports : { fn ( ) { return 42 ; } } ,
523- } ) ;
547+ async function assertCoreModuleMockWorksInBothModuleSystems ( t , specifier , options ) {
548+ const coreMock = t . mock . module ( specifier , options ) ;
524549
525- let esmImpl = await import ( 'readline' ) ;
526- let cjsImpl = require ( 'readline' ) ;
550+ let esmImpl = await import ( specifier ) ;
551+ let cjsImpl = require ( specifier ) ;
527552
528553 assert . strictEqual ( esmImpl . fn ( ) , 42 ) ;
529554 assert . strictEqual ( cjsImpl . fn ( ) , 42 ) ;
530555
531556 coreMock . restore ( ) ;
532- esmImpl = await import ( 'readline' ) ;
533- cjsImpl = require ( 'readline' ) ;
557+ esmImpl = await import ( specifier ) ;
558+ cjsImpl = require ( specifier ) ;
534559
535560 assert . strictEqual ( typeof esmImpl . cursorTo , 'function' ) ;
536561 assert . strictEqual ( typeof cjsImpl . cursorTo , 'function' ) ;
562+ }
563+
564+ test ( 'core module mocks can be used by both module systems' , async ( t ) => {
565+ await assertCoreModuleMockWorksInBothModuleSystems ( t , 'readline' , {
566+ namedExports : { fn ( ) { return 42 ; } } ,
567+ } ) ;
537568} ) ;
538569
539570test ( 'node:- core module mocks can be used by both module systems' , async ( t ) => {
540- const coreMock = t . mock . module ( 'node:readline' , {
571+ await assertCoreModuleMockWorksInBothModuleSystems ( t , 'node:readline' , {
541572 namedExports : { fn ( ) { return 42 ; } } ,
542573 } ) ;
543-
544- let esmImpl = await import ( 'node:readline' ) ;
545- let cjsImpl = require ( 'node:readline' ) ;
546-
547- assert . strictEqual ( esmImpl . fn ( ) , 42 ) ;
548- assert . strictEqual ( cjsImpl . fn ( ) , 42 ) ;
549-
550- coreMock . restore ( ) ;
551- esmImpl = await import ( 'node:readline' ) ;
552- cjsImpl = require ( 'node:readline' ) ;
553-
554- assert . strictEqual ( typeof esmImpl . cursorTo , 'function' ) ;
555- assert . strictEqual ( typeof cjsImpl . cursorTo , 'function' ) ;
556574} ) ;
557575
558576test ( 'CJS mocks can be used by both module systems' , async ( t ) => {
@@ -666,6 +684,55 @@ test('defaultExports work with ESM mocks in both module systems', async (t) => {
666684 assert . strictEqual ( require ( fixturePath ) , defaultExport ) ;
667685} ) ;
668686
687+ test ( 'exports option works with core module mocks in both module systems' , async ( t ) => {
688+ await assertCoreModuleMockWorksInBothModuleSystems ( t , 'readline' , {
689+ exports : { fn ( ) { return 42 ; } } ,
690+ } ) ;
691+ } ) ;
692+
693+ test ( 'exports option supports default for CJS mocks in both module systems' , async ( t ) => {
694+ const fixturePath = fixtures . path ( 'module-mocking' , 'basic-cjs.js' ) ;
695+ const fixture = pathToFileURL ( fixturePath ) ;
696+ const defaultExport = { val1 : 5 , val2 : 3 } ;
697+
698+ t . mock . module ( fixture , {
699+ exports : {
700+ default : defaultExport ,
701+ val1 : 'mock value' ,
702+ } ,
703+ } ) ;
704+
705+ const cjsMock = require ( fixturePath ) ;
706+ const esmMock = await import ( fixture ) ;
707+
708+ assert . strictEqual ( cjsMock , defaultExport ) ;
709+ assert . strictEqual ( esmMock . default , defaultExport ) ;
710+ assert . strictEqual ( cjsMock . val1 , 'mock value' ) ;
711+ assert . strictEqual ( esmMock . val1 , 'mock value' ) ;
712+ assert . strictEqual ( cjsMock . val2 , 3 ) ;
713+ } ) ;
714+
715+ test ( 'exports option supports default for ESM mocks in both module systems' , async ( t ) => {
716+ const fixturePath = fixtures . path ( 'module-mocking' , 'basic-esm.mjs' ) ;
717+ const fixture = pathToFileURL ( fixturePath ) ;
718+ const defaultExport = { mocked : true } ;
719+
720+ t . mock . module ( fixture , {
721+ exports : {
722+ default : defaultExport ,
723+ val1 : 'mock value' ,
724+ } ,
725+ } ) ;
726+
727+ const esmMock = await import ( fixture ) ;
728+ const cjsMock = require ( fixturePath ) ;
729+
730+ assert . strictEqual ( esmMock . default , defaultExport ) ;
731+ assert . strictEqual ( esmMock . val1 , 'mock value' ) ;
732+ assert . strictEqual ( cjsMock , defaultExport ) ;
733+ assert . strictEqual ( cjsMock . val1 , 'mock value' ) ;
734+ } ) ;
735+
669736test ( 'wrong import syntax should throw error after module mocking' , async ( ) => {
670737 const { stdout, stderr, code } = await common . spawnPromisified (
671738 process . execPath ,
0 commit comments