Модульное тестирование, что localStorage.getItem был вызван на документ готов? - PullRequest
0 голосов
/ 21 января 2020

У меня есть следующий код, посредством которого элемент localStorage проверяется на готовом документе. Если элемент localStorage еще не был установлен, он установлен:

$(document).ready(function () {             
   checkIfLoginTracked();                
})

function checkIfLoginTracked() {
   if (localStorage.getItem("loginHasBeenTracked") === null) {
         localStorage.setItem("loginHasBeenTracked", true);
   }
}

Однако я пытаюсь узнать, как лучше всего провести юнит-тестирование?

Я использую Qunit и Sinon и до сих пор пробовал следующее в тестовом блоке (следил за методом локального хранилища и проверял, что он был вызван с правильным аргументом)

var spy = sinon.spy(window.localStorage, "getItem");
assert.ok(spy.calledWith("loginHasBeenTracked", true));

Это возвращает ложь и говорит, что не называется. Я не знаю, упускаю ли я что-то очевидное или, может быть, это из-за того, что на document.ready это сложно проверить? Может кто-нибудь, пожалуйста, укажите мне в правильном направлении?

1 Ответ

0 голосов
/ 03 февраля 2020

Вот решение для модульного тестирования, среда тестирования: node. Если ваша тестовая среда browser, вам не нужен модуль jsdom. И вы должны заглушить объект localStorage на window объекте, а не global объекте.

index.js:

const $ = require("jquery");

$(document).ready(function() {
  checkIfLoginTracked();
});

function checkIfLoginTracked() {
  if (localStorage.getItem("loginHasBeenTracked") === null) {
    localStorage.setItem("loginHasBeenTracked", true);
  }
}

index.test.js:

const proxyquire = require("proxyquire");
const sinon = require("sinon");
const jsdom = require("jsdom");

describe("59840852", () => {
  before(() => {
    const html = '<!doctype html><html><head><meta charset="utf-8">' + "</head><body></body></html>";
    const url = "http://localhost";
    const document = new jsdom.JSDOM(html, { url });
    const window = document.window;
    global.document = window.document;
    global.window = window;
  });
  it("should set item", () => {
    const localStorageStub = {
      getItem: sinon
        .stub()
        .withArgs("loginHasBeenTracked")
        .returns(null),
      setItem: sinon.stub(),
    };
    global.localStorage = localStorageStub;
    const jqueryStub = { ready: sinon.stub().callsFake((handler) => handler()) };
    const $ = sinon.stub().callsFake(() => jqueryStub);
    proxyquire("./", { jquery: $ });
    sinon.assert.calledWithExactly($, document);
    sinon.assert.calledWithExactly(localStorage.getItem, "loginHasBeenTracked");
    sinon.assert.calledWithExactly(localStorage.setItem, "loginHasBeenTracked", true);
  });

  it("should do nothing if login has been tracked", () => {
    const localStorageStub = {
      getItem: sinon
        .stub()
        .withArgs("loginHasBeenTracked")
        .returns(true),
      setItem: sinon.stub(),
    };
    global.localStorage = localStorageStub;
    const jqueryStub = { ready: sinon.stub().callsFake((handler) => handler()) };
    const $ = sinon.stub().callsFake(() => jqueryStub);
    proxyquire("./", { jquery: $ });
    sinon.assert.calledWithExactly($, document);
    sinon.assert.calledWithExactly(localStorage.getItem, "loginHasBeenTracked");
    sinon.assert.notCalled(localStorage.setItem);
  });
});

Результаты модульных испытаний со 100% покрытием:

  59840852
    ✓ should set item (93ms)
    ✓ should do nothing if login has been tracked


  2 passing (149ms)

---------------|----------|----------|----------|----------|-------------------|
File           |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
---------------|----------|----------|----------|----------|-------------------|
All files      |      100 |      100 |      100 |      100 |                   |
 index.js      |      100 |      100 |      100 |      100 |                   |
 index.test.js |      100 |      100 |      100 |      100 |                   |
---------------|----------|----------|----------|----------|-------------------|

Исходный код: https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/59840852

...