# How to create tests for Middleware

This article describes how to write tests for Middleware.

Tests are a great tool not only to guarantee the correct behavior of Middleware but also recommended for its creation, using a test-driven approach.

# Create the fixtures

Run the npm run create:fixtures command to automatically generate the fixtures.

TIP

This command will download the HTML of the desired page into the tenant.com/index/src/fixtures folder, creating it if it doesn't exist.

# Install Middleware test utils

Add the Middleware test utils package as a development dependency, which contains the necessary tools to successfully configure and run the tests.

npm i --save-dev @marfeel/middlewares-test-utils

# Create the test file

Create a .test.ts file in the tenant.com/index/src/middlewares/your-provider folder of the tenant.

Naming

The file name depends on the hook you are using:

The folder name should match the provider:

  • tenant.com/index/src/middlewares/facebookpixel
  • tenant.com/index/src/middlewares/youtube-playlist

# OnExtraction test file

In the on-extraction.test.ts file, load the fixture we just extracted by using the loadFixture method. Import it from the middlewares-test-utils package and call it passing the filename of your fixture file as a parameter:

import { loadFixture } from '@marfeel/middlewares-test-utils';

const document = await loadFixture('how-to-improve-ad-viewability.html');

The loadFixture will load your fixture into a document the Middleware can work on. The method also accepts a URL as a second optional parameter: use it to set the location property of the generated HTML Document:

import { loadFixture } from '@marfeel/middlewares-test-utils';

const document = await loadFixture('how-to-improve-ad-viewability.html', 'https://www.mysite.com/somepage');

If no second parameter is passed loadFixture will set document.location with the default value: https://www.example.com/index.

When working on onExtraction Hook, set up the Middleware execution. The runMiddleware method allows you to run a Middleware in a given document.

runMiddleware requires two arguments:

  • Document: The document the Middleware will be executed on, in this case, the output of the loadFixture method.
  • onExtractionMiddleware: The Middleware to execute.
import { onExtraction } from './on-extraction';

const result = await runMiddleware(document, onExtraction);

To finish the test, configure the describe block (opens new window) validating the result of the middleware execution is correct by comparing it to the expected result.

The whole test will look something like this:

import { loadFixture, runMiddleware } from '@marfeel/middlewares-test-utils';

import { onExtraction } from './on-extraction';

describe('Poll Daddy', () => {
  describe('OnExtraction', () => {
    test('returns the pollId', async() => {
      const document = await loadFixture('how-to-improve-ad-viewability.html');

      const result = await runMiddleware(document, onExtraction);

      expect(result).toEqual({
        pollId: '10582522'
      });
    });
  });
});

# OnBrowser test file

In the on-browser.test.ts you need to mock the window object before you can configure the describe block (opens new window).

Import the ts-auto-mock package (opens new window) which is already accessible by default and use the createMock method (opens new window) to mock the window with the structure our middleware expects.

createMock

import { createMock} from 'ts-auto-mock'


  const window = createMock<Window>({
    document: {
        referrer: 'https://google.com/'
    },
    location: {
        href: 'https://marfeel.com/docs/'
    }
  });

Then, import the onBrowser function and execute it directly on the mocked window object to expect the desired result.

The whole test will look something like this:

import { onBrowser } from './on-browser';
import { createMock} from 'ts-auto-mock'


  const window = createMock<Window>({
    document: {
        referrer: 'https://google.com/'
    },
    location: {
        href: 'https://marfeel.com/docs/'
    }
  });

describe('FacebookPixel', () => {
  describe('OnBrowser', () => {
    test('returns the referrer', async() => {
      const result = await onBrowser({window});

      expect(result.extraUrlParams.rl).toEqual('https://google.com');
    });

    test('returns the location', async() => {
      const result = await onBrowser({window});

      expect(result.extraUrlParams.dl).toEqual('https://marfeel.com/docs/');
    });
  });
});