httptoolkit / httptoolkit-server

The backend of HTTP Toolkit

Home Page:https://httptoolkit.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cannot read property 'prototype' of undefined

alexburley opened this issue · comments

commented

Hey, trying to run some integration tests locally, this is the error I get. I've got a feeling this is to do with Jest as I know they override requiring. Posting here for tracking.

image

Hmm, this is very interesting. I haven't tested with jest, so I can't be sure, but it sounds plausible.

What's happening here is that HTTP Toolkit is wrapping require('module')._load, which is the internal function used to actually load modules. It wraps it so that certain modules can be configured before the require completes, to inject certificates and proxy settings.

In theory it should be fine: jest can wrap require() however it likes, and any time it falls back to the real require() to load real modules, those will hit these wrappers as normal. Clearly it's not working quite right though.

It looks like this is failing inside request-promise-core, which might be relevant. Can you let me know which version of jest, request, request-promise-core & request-promise-native you're using? I'll do some testing and see what I can come up with.

commented

jest: 24.9.0
request-promise-core: 1.1.2
request-promise-native: 1.0.7
request: 2.88.0

I'm afraid I can't seem to reproduce this.

I've set up a test with each of those versions, and the below prints the right status code, passes, and shows the intercepted request in HTTP Toolkit with no problems:

const request = require('request-promise-native');

test('can make requests', async () => {
  const result = await request.get('https://example.com', {
    resolveWithFullResponse: true
  });

  console.log('Received', result.statusCode);
  expect(result.statusCode).toBe(200);
});

Tested with jest and jest --runInBand, in case that makes a difference, still works fine.

Seems there's something more complex going on. Is there any way you can share the code that's failing, or some minimal test case of the issue?

Hi @alexburley any updates on this? I'm a bit stuck for now since I can't reproduce it, but if you can give me a broken example or some more detail then I'd be happy to take a closer look.

commented

I'll have a deeper look into this when I get the chance, as running jest on some other test suites seems to work.

An example of a test I'm running. Falafel is a library we use to wrap code structure to make http requests, this sounds like it would be an issue but the tests are failing even with instantiation of falafel commented out. Dotenv doesn't seem to cause a problem either.

const Falafel = require('@trayio/falafel');
new Falafel().wrap({ directory: __dirname + '/../../' });
require('dotenv').config();
describe('mysql', () => {
	const auth = {
		authentication: {
			user: process.env.sql_username,
			password: process.env.sql_password,
			host: process.env.sql_host,
			database: process.env.sql_database,
			port: process.env.sql_port,
		},
	};
	const tableName = 'Persons';
	describe('ExecuteSql - Create Table', () => {
		it('Should create a table', () => {
			return falafel.mysql
				.executeSql({
					...auth,
					sql: `CREATE TABLE ${tableName} (
						PersonID int NOT NULL PRIMARY KEY AUTO_INCREMENT,
						FirstName varchar(255),
            LastName varchar(255),
            Age int
					);`,
				})
				.then(output => {
					expect(output.result).toBeDefined();
				});
		});
	});
}):

Package.json dependencies can be seen below

	"scripts": {
		"test:integration": "jest tests/integration/ --runInBand"
	},
	"dependencies": {
		"@trayio/falafel": "^1.23.2",
		"knex": "^0.16.3",
		"mysql": "^2.17.1"
	},
	"devDependencies": {
		"body-parser": "^1.17.1",
		"dotenv": "^8.1.0",
		"eslint": "^6.5.1",
		"eslint-config-prettier": "^6.3.0",
		"eslint-plugin-jest": "^22.17.0",
		"eslint-plugin-prettier": "^3.1.1",
		"express": "^4.15.2",
		"generate-schema": "^2.4.0",
		"jest": "^24.9.0",
		"node-dev": "^4.0.0",
		"prettier": "^1.18.2"
	},

@alexburley any updates on this?

One thing I've found in some other testing is that adding tools which significantly change how node runs can cause odd behaviour with HTTP Toolkit interception. The clearest example is things like Istanbul & other code coverage tools, which intercept everything, from node startup to module loading.

So far I've only seen them failing to be intercepted, rather than failing to make HTTP requests at all, but I can imagine there could be other cases where that might happen. Are you using anything like that in these tests?