Использование шпионов и моков на сложных объектах с помощью Jest - PullRequest
0 голосов
/ 06 августа 2020

Я новичок в тестировании и написании тестов для javaScript кодовой базы с использованием Jest. Код охватывает некоторые нишевые варианты использования, поскольку он условно вводится и выполняется браузером во время загрузки страницы. В любом случае, у меня проблемы с макетом пользовательских объектов. Вот рассматриваемая функция:

const setEnterpriseCookie = () => {
        // Get the current page uri
        let path = window.location.pathname;

        // Matches all pages containing '/regex_expression'
        if (path.match(/.*\/regex_expression.*/)) {
            window.TOOL.cookie.setCookie(...args);
        }
    };

Насколько я понимаю, мне нужно издеваться над обоими window.location.pathname, чтобы вернуть строку, и мне нужно издеваться над window.TOOL.cookie.setCookie() как с фиктивной функцией. Вот моя попытка пройти тест:

var windowSpy;

describe('Tests for the page-specific-methods.js file', () => {

    beforeEach( () => {
        windowSpy = jest.spyOn(global, 'window', 'get');
    });

    afterEach( () => {
        windowSpy.mockRestore();
    })

    test('Test the page path detecting the enterprise string', () => {
        windowSpy.mockImplementation( () => ({
            location: {
                pathname: '/enterprise/contact',
            },
            TOOL: {
                cookie: {
                    setCookie: jest.fn(),
                },
            },
        }));

        setEnterpriseCookie();
        
        expect(window.TOOL.cookie.setCookie).toBeCalledTimes(1);
        expect(window.TOOL.cookie.setCookie).toHaveBeenLastCalledWith(...args);
    })
});

Тест не проходит, так как window.TOOL.cookie.setCookie вызывается 0 раз. Я погрузился в процесс и обнаружил, что window.location.pathname выполняется, как ожидалось, и, таким образом, код вводит условное выражение, которое вызывает window.TOOL.cookie.setCookie. Я думаю, проблема где-то в том, как я издеваюсь над window.TOOL.cookie.setCookie, но мне не удалось найти никакой справки, которая бы описывала, как насмехаться над методами так много. Глубоко.

Заранее спасибо за помощь!

1 Ответ

0 голосов
/ 06 августа 2020

Просто используйте Object.defineProperty () определяет свойство непосредственно на window объекте.

Например,

index.js:

const setEnterpriseCookie = (...args) => {
  let path = window.location.pathname;
  if (path.match(/.*\/enterprise.*/)) {
    window.TOOL.cookie.setCookie(...args);
  }
};

exports.setEnterpriseCookie = setEnterpriseCookie;

index.test.js:

const { setEnterpriseCookie } = require('./');

describe('63274598', () => {
  describe('Tests for the page-specific-methods.js file', () => {
    test('Test the page path detecting the enterprise string', () => {
      Object.defineProperty(window, 'location', {
        value: { pathname: '/enterprise/contact' },
      });
      Object.defineProperty(window, 'TOOL', {
        value: {
          cookie: {
            setCookie: jest.fn(),
          },
        },
      });
      setEnterpriseCookie('123');

      expect(window.TOOL.cookie.setCookie).toBeCalledTimes(1);
      expect(window.TOOL.cookie.setCookie).toHaveBeenLastCalledWith('123');
    });
  });
});

результат модульного теста:

 PASS  stackoverflow/63274598/index.test.js (13.923s)
  63274598
    Tests for the page-specific-methods.js file
      ✓ Test the page path detecting the enterprise string (4ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |       50 |     100 |     100 |                   
 index.js |     100 |       50 |     100 |     100 | 3                 
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        15.975s
...