Модульное тестирование функций, связанных с пользовательским интерфейсом - PullRequest
2 голосов
/ 18 июня 2020

Я пытаюсь понять концепцию модульного тестирования и заблудиться с тестированием функций, связанных с пользовательским интерфейсом, например:

const hideElem = elem => {
  elem.classList.add('js-hidden')
}

или это:

const getInputValue = (inputElem) => {
  let inputEl = document.querySelector(inputElem)

  return inputEl.value
}

или это:

const cleanInput = input => {
  const inputEl = document.querySelector(input)
  inputEl.value = ''
}

Нужно ли мне покрывать такие функции модульными тестами в Jest? Если да, не могли бы вы объяснить, как здесь объединить Jest и DOM-вещи?

1 Ответ

0 голосов
/ 22 июня 2020

Модульное тестирование должно быть сосредоточено на коде logi c, а не на том, что связано с DOM в браузере. Это НЕ тестирование e2e. Для модульного тестирования мы можем создавать и использовать фиктивные объекты для проверки правильности кода logi c.

Модульное тестирование не должно зависеть от какой-либо внешней среды, такой как браузеры, сторонние службы. Другими словами, нам нужно имитировать связанные с dom вещи, чтобы код модульного теста имел хорошую изоляцию.

Для среды node.js мы можем использовать jsdom для эмуляции вещей, связанных с dom и веб-API.

В целом цель проекта - имитировать достаточное количество подмножества веб-браузера, чтобы его можно было использовать для тестирования и анализа реальных веб-приложений.

Например

index.js:

const hideElem = (elem) => {
  elem.classList.add('js-hidden');
};

const getInputValue = (inputElem) => {
  let inputEl = document.querySelector(inputElem);

  return inputEl.value;
};

const cleanInput = (input) => {
  const inputEl = document.querySelector(input);
  inputEl.value = '';
};

export { hideElem, getInputValue, cleanInput };

index.test.js:

import { hideElem, getInputValue, cleanInput } from './';

describe('62455692', () => {
  describe('hideElem', () => {
    it('should hide elem', () => {
      const mElem = { classList: { add: jest.fn() } };
      hideElem(mElem);
      expect(mElem.classList.add).toBeCalledWith('js-hidden');
    });
  });

  describe('getInputValue', () => {
    it('should get input value', () => {
      const mInputElem = { value: 'mocked value' };
      jest.spyOn(document, 'querySelector').mockReturnValueOnce(mInputElem);
      const actual = getInputValue('#foo');
      expect(actual).toBe('mocked value');
      expect(document.querySelector).toBeCalledWith('#foo');
      document.querySelector.mockRestore();
    });
  });

  describe('cleanInput', () => {
    it('should clean input', () => {
      const mInputElem = { value: 'mocked value' };
      jest.spyOn(document, 'querySelector').mockReturnValueOnce(mInputElem);
      cleanInput('#foo');
      expect(mInputElem.value).toBe('');
      expect(document.querySelector).toBeCalledWith('#foo');
      document.querySelector.mockRestore();
    });
  });
});

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

 PASS  stackoverflow/62455692/index.test.js (10.489s)
  62455692
    hideElem
      ✓ should hide elem (5ms)
    getInputValue
      ✓ should get input value (2ms)
    cleanInput
      ✓ should clean input (1ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 index.js |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        11.874s, estimated 13s
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...