sahilrajput03

Jest and expect

Quick Links:

Bare setup with just expect and typescript setup:

Remove default console.log format of jest

Also, added on stackoverflow: Cilck here

Create file: logger-utils.ts with following code:

/**
 * Why use `jestLogger` in tests instead of regular console.log in our tests file?
 * > Because the default version of console.log in tests environment is manipulated by Jest
 * environment so that each log prints the line and filename of the log. This ends up in
 * lot of verbosity and thus hinders the debugging experience to some users.
 * Usage:
 * In any test file, use below code on top of file:

  import { jestLogger } from '../../utils/logger-utils';
  console.log = jestLogger;

  Note: We don't want to directly use `jestLogger` because we do not
  get eslint waring of no-console-log.
  So, we should override console.log so that we get eslint warnings and
  we don't end up getting log statements in our tests.

*/

// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
export const jestLogger = require('console').log;

and now in your tests files, you can use:

// TOP OF THE FILE
import { jestLogger } from '../../utils/logger-utils';
console.log = jestLogger; // this thorws warning but let it be because we anyway we want to remove this after testing is complete.

// in your tets
console.log('hello');

FYI: Other accepted solution from stackoverflow:

Source (stackoverflow): Click here

const jestConsole = console;

beforeEach(() => {
  global.console = require('console');
});

afterEach(() => {
  global.console = jestConsole;
});

more assertion helpers for .toEqual

My Luxon Notes: Learn Luxon: Click here

// For services:
expect(...).toEqual({
	_id: expect.any(mongoose.Types.ObjectId),
	createdAt: expect.any(Date),
	updatedAt: expect.any(Date),
})

// For e2e:
expect(...).toEqual({
	_id: expect.stringMatching(SIMPLE_MONGODB_ID_REGEX),
	createdAt: expect.any(String),
	updatedAt: expect.any(String),
	startDate: '2022-10-24T00:00:00.000Z', // using dates with `luxon.DateTime.fromISO('2022-10-17T00:00:00Z').toJSDate().toISOString()`
	endDate: '2022-10-25T23:59:59.000Z', // using dates with `luxon.DateTime.fromISO('2022-10-25T23:59:59Z').toJSDate().toISOString()`
	// NOTE the difference of extra .000 before Z
})

File deletion and exists check with jest

it.only('if given path is exists then it will return that same path', async () => {
  function runTest() {
    const tempFilePath = path.join(os.tmpdir(), 'myfile.jpg');
    const fh = fs.openSync(tempFilePath, 'w');
    fs.writeSync(fh, '.', 3);
    fs.closeSync(fh);
    expect(existsSync(tempFilePath)).toBe(true);
    unlinkSync(tempFilePath);
    expect(existsSync(tempFilePath)).toBe(false);
  }
  for (let i = 0; i < 10_000; i += 1) {
    console.log('iter:', i);
    runTest();
  }
});

What’s the difference between “foo.spec.ts” and “foo.test.ts”?

Source: Click here

image

How to check multiple arguments on multiple calls for jest spies

Source: Click here

image

1/2 mock

Source (Jest Docs): Click here

const myMockFn = jest
  .fn(() => 'default')
  .mockImplementationOnce(() => 'first call')
  .mockImplementationOnce(() => 'second call');

console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn());
// > 'first call', 'second call', 'default', 'default'

Learn about mock functions and using jest.spyOn(..., ...).mockImplementation(() => Promise.resolve(undefined)) along with toHaveBeenCalledWith assertions

(check: Why use mock testing functions in telegram slasher-private-channel to know specifics learned)

Medium Article suggested by Eric’s Suggested Article: Click here

image

For bettter testing use expect().toEqual(...)

Tip: If you don’t have string matches you can use store sample date in .json file as well.

```js import expect from ‘expect’
const SIMPLE_MONGODB_ID_REGEX = /^[a-f\d]{24}$/i // 24 characters ~Sahil

const response = [
	{
		_id: '63ab12b2fa6c5356d22a298d',
		userName: 'yolo',
		firstName: 'Nelson Mandela',
		profilePic: 'http://localhost:4444/placeholders/default_user_icon.png',
	},
]

// Learn Usage of:
// 1. .toEqual(...)
// 2. expect.stringMatching(...)
// 3. expect.not.stringContaining(...)

expect(response).toEqual([
	{
		_id: expect.stringMatching(SIMPLE_MONGODB_ID_REGEX),
		userName: 'yolo',
		firstName: 'Nelson Mandela',
		profilePic: 'http://localhost:4444/placeholders/default_user_icon.png',
	},
])
expect([{name: 'sahil rajput'}]).toEqual([
	{
		name: expect.stringContaining('sahil'),
	},
])
expect([{name: 'sahil rajput'}]).toEqual([
	{
		name: expect.stringContaining('rajput'),
	},
])
expect([{name: 'sahil rajput'}]).toEqual([
	{
		name: expect.not.stringContaining('om'),
	},
])
  	```

Testing asynch operation with jest

  describe.only('something', () => {
    it.only('shoudl it be?', (done) => {
      console.log('hello');
      done() // if done is not called then the test will not pass at all. In fact the setTimeout warning is thrown.
    });
  });

Socket.io Testing with jest:

Click here: Official Docs - Click here

Amazingly defined funcion to wait for a callback function but reject after 2 seconds if didn’t receive the event, YO!!

image

Jest debugging command from official docs:

node --inspect-brk node_modules/.bin/jest --runInBand [any other arguments here]

Define test timeout for a individual test like that

  it('does a lot of stuff exceeding default 5 sec timeout', async () => {
    // ...
  }, 10000)

You can define jest config for a single file basis by that

image