node-mysql2 icon indicating copy to clipboard operation
node-mysql2 copied to clipboard

Error running tests with Jest using mysql2 1.7.0

Open SiroDiaz opened this issue 4 years ago • 9 comments

I get the following error after updating from mysql2@^1.6.5 to mysql2@^1.7.0.

ReferenceError: You are trying to `import` a file after the Jest environment has been torn down.

      at Object.getCodec (node_modules/mysql2/node_modules/iconv-lite/lib/index.js:65:27)
      at Object.getDecoder (node_modules/mysql2/node_modules/iconv-lite/lib/index.js:127:23)
      at Object.<anonymous>.exports.decode (node_modules/mysql2/lib/parsers/string.js:10:25)
      at Packet.readNullTerminatedString (node_modules/mysql2/lib/packets/packet.js:384:25)
      at Function.fromPacket (node_modules/mysql2/lib/packets/handshake.js:58:33)
C:\Users\siroc\repositories\sphinxql\node_modules\mysql2\node_modules\iconv-lite\lib\index.js:106
                throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '"+enc+"')");
                ^

Error: Encoding not recognized: 'cesu8' (searched as: 'cesu8')
    at Object.getCodec (C:\Users\siroc\repositories\sphinxql\node_modules\mysql2\node_modules\iconv-lite\lib\index.js:106:23)
    at Object.getDecoder (C:\Users\siroc\repositories\sphinxql\node_modules\mysql2\node_modules\iconv-lite\lib\index.js:127:23)
    at Object.<anonymous>.exports.decode (C:\Users\siroc\repositories\sphinxql\node_modules\mysql2\lib\parsers\string.js:10:25)
    at Packet.readNullTerminatedString (C:\Users\siroc\repositories\sphinxql\node_modules\mysql2\lib\packets\packet.js:384:25)
siroc\repositories\sphinxql\node_modules\mysql2\lib\packets\handshake.js:58:33)
    at ClientHandshake.handshakeInit (C:\Users\siroc\repositories\sphinxql\node_modules\mysql2\lib\commands\client_handshake.js:92:40)
    at ClientHandshake.execute (C:\Users\siroc\repositories\sphinxql\node_modules\mysql2\lib\commands\command.js:39:22)
    at Connection.handlePacket (C:\Users\siroc\repositories\sphinxql\node_modules\mysql2\lib\connection.js:449:32)
    at PacketParser.Connection.packetParser.p [as onPacket] (C:\Users\siroc\repositories\sphinxql\node_modules\mysql2\lib\connection.js:72:12)
    at PacketParser.executeStart (C:\Users\siroc\repositories\sphinxql\node_modules\mysql2\lib\packet_parser.js:75:16)

If you want to see the project with all updated (except the mysql2 package) to replicate the problem use https://github.com/SiroDiaz/sphinxql. Note that it is under develop branch. Just try to update mysql2 to latest version(1.7.0), start Manticore search 3.1.0 and run jest tests.

Start Manticore search daemon:

cd __tests__
searchd --config sphinx.conf

SiroDiaz avatar Oct 20 '19 18:10 SiroDiaz

How do I run tests? I guess I need some preparation step, getting Failed: "no such local index 'rt' error.

My steps:

  • git clone https://github.com/SiroDiaz/sphinxql && cd sphinxql && git co develop & npm install
  • start Manticore with docker run -it -p 9307:9306 manticoresearch/manticore
  • npm test

sidorares avatar Oct 27 '19 10:10 sidorares

I'm trying to run docker run to follow your steps and Manticore container doesn't find the local sphinx.conf file for testing. So i recommend you to install Manticore without Docker this time and run searchd. I have reported the issue with the Manticore Docker image (for Windows).

If you are using other OS different to Windows 10 Home, you can try to run the following command changing paths docker run --name manticore -v ~/sphinxql/__tests__/:/etc/sphinxsearch/ -v ~/sphinxql/__tests__/data/:/var/lib/manticore/data -v ~/sphinxql/__tests__/:/var/log/manticore -p 9307:9306 -d manticoresearch/manticore

The sphinx.conf is the configuration file and that file for tests lives in /sphinxql/__tests__ directory and logs and data folders are relative to the project location. So, don't forget to use searchd being inside tests directory.

SiroDiaz avatar Oct 27 '19 16:10 SiroDiaz

I started it with docker run -it -v $PWD/__tests__:/etc/sphinxsearch -p 9307:9306 manticoresearch/manticore and now some other tests fail

sidorares avatar Oct 28 '19 02:10 sidorares

There's two errors here. The second one:

Error: Encoding not recognized: 'cesu8' (searched as: 'cesu8')

This can be resolved using this code (tests/setup.js):

// Little fix for Jest, see https://stackoverflow.com/a/54175600
require('mysql2/node_modules/iconv-lite').encodingExists('foo');

Then wire it in using jest.config.json:

{
  "setupFilesAfterEnv": ["<rootDir>/tests/setup.js"]
}

halfer avatar May 08 '20 23:05 halfer

<rootDir>/

Thanks for this hack.

tksilicon avatar May 24 '20 17:05 tksilicon

Thank you!!!

jpsala avatar Jul 11 '20 06:07 jpsala

This is ugly but worked )))

jokermt235 avatar Feb 02 '21 06:02 jokermt235

Not working with native ESM (type=module).

What's going on?

damianobarbati avatar Jan 21 '22 15:01 damianobarbati

I tried:

import iconv from 'mysql2/node_modules/iconv-lite';

iconv.encodingExists('foo');

But I get this error:

 Cannot find module 'mysql2/node_modules/iconv-lite' from 'src/tests-utils/jestSetupAfterEnv.ts'

Eventhough the file does exist (but maybe its not part of the build which causes the error, but my linter is fine with this line too).

I also tried this:

import iconv from 'iconv-lite';

iconv.encodingExists('foo');

But I still get the error. Is this really "foo" or should I use iconv.encodingExists('cesu8')?

In my case I feel its related to using a package called supertest (which is supposed to mount the express app for me). Because when I run the database initialisation myself there is no issue (I don't even get the error in the first place).

Edit

I think I found my mistake, I had the application setup script in my entry point file (/index.ts), that more or less look like this:

export async function startApplication() {
    const app = express();
    const dbConnection = await assertDbAvailable();
    useCors(app);
    useUserSession(app);
    useRouters(app);
    const apollo = await useApollo(app);
    if (process.env.NODE_ENV !== 'test') {
        const server = startServer(app);
        process.on('SIGTERM', () => {
            server.close();
        });
    }
    process.on('SIGTERM', () => {
        dbConnection.close();
        apollo.stop();
    });
    return app;
}

startApplication();

In my tests I had the following:

import { startApplication } from '../..';
import { Express } from 'express';

describe('Endpoint X test', () => {
    let wasEmpty = false;
    let app: Express;
    beforeAll(async () => {
        app = await startApplication();
        await assertDatabaseEmpty();
        wasEmpty = true;
    });
    afterAll(async () => {
        if (wasEmpty) {
            await cleanDatabase();
        }
    });
});

The mistake here is that with this code, startApplication is called twice which seems to cause the above mentioned issue (in my case). I simply moved startApplication function to another file, and imported it from there in both my tests and the entrypoint file. I didn't need any hack and left my application tests as they were before having this error for the first time.

cglacet avatar Sep 12 '23 11:09 cglacet