如何通过Jasmine在JS中测试(单元测试)箭头功能?

时间:2019-12-26 11:20:08

标签: javascript jasmine

我已经完成了一个小项目“ Notes”,现在尝试使用Jasmine对其进行测试。但是由于这是我的第一个使用模块样式和私有功能模仿的脚本,所以我不理解如何测试脚本的业务逻辑,因为Jasmine根本看不到我的箭头函数。请帮助我开始测试。

// eslint-disable-next-line func-names
const NotesList = ((function () {
  const NOTE_TITLE = 'notesList';

  const initNotesList = () => {
    if (localStorage.getItem(NOTE_TITLE)) {
      return JSON.parse(localStorage.getItem(NOTE_TITLE));
    }

    return [];
  };

  let notesList = initNotesList();

  const saveData = (data) => {
    notesList = [...data];
    localStorage.setItem(NOTE_TITLE, JSON.stringify(notesList));
  };

  const addNote = (note) => {
    if (notesList.includes(note)) {
      return {
        done: false,
        error: 'The note is in the notes list already',
      };
    }

    saveData([...notesList, note]);
    return {
      done: true,
    };
  };

  const removeNote = (note) => {
    const filteredNotesList = notesList.filter((item) => item !== note);
    if (filteredNotesList.length === notesList.length) {
      return {
        done: false,
        error: 'Note doesn\'t exist',
      };
    }

    saveData(filteredNotesList);
    return { done: true };
  };

  return {
    getNotesList() {
      return notesList;
    },
    addItem(item) {
      return addNote(item);
    },
    removeItem(item) {
      return removeNote(item);
    },
  };
})());

const STYLES = {
  show: 'd-block',
};

const UI = {
  noteValue: document.querySelector('#note-value'),
  addNote: document.querySelector('#add-note'),
  removeNote: document.querySelector('#remove-note'),
  errorMessage: document.querySelector('#error-message'),
  list: document.querySelector('#list'),

  renderNotesList() {
    this.clearNotesList();
    NotesList.getNotesList().forEach((item) => {
      const li = document.createElement('li');
      li.innerText = item;
      this.list.append(li);
    });
  },

  clearNotesList() {
    this.list.innerText = '';
  },

  handleNotesListResponse(result) {
    if (result.done) {
      this.noteValue.value = '';
      this.errorMessage.classList.remove(STYLES.show);
      this.renderNotesList();
    } else {
      this.errorMessage.innerText = result.error;
      this.errorMessage.classList.add(STYLES.show);
    }
  },
};

UI.addNote.addEventListener('click', (event) => {
  event.preventDefault();
  const result = NotesList.addItem(UI.noteValue.value);
  UI.handleNotesListResponse(result);
});

UI.removeNote.addEventListener('click', (event) => {
  event.preventDefault();
  const result = NotesList.removeItem(UI.noteValue.value);
  UI.handleNotesListResponse(result);
});

UI.renderNotesList();
body{font-family:"Roboto Condensed",sans-serif;font-size:16px}header{background:none}.nav-link{font-size:20px}.container{max-width:1200px;background-image:url(../images/blue-snow.png)}.container-header{max-width:1200px}.container-footer{max-width:1200px}footer li{display:inline;padding-right:5px;padding-bottom:5px}ul li a :hover{transform:rotate(1turn);transition:0.5s ease-in}html{scroll-behavior:smooth}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <link rel="stylesheet"
        href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
        integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
        crossorigin="anonymous">
  <link
      href="https://fonts.googleapis.com/css?family=Roboto+Condensed&display=swap"
      rel="stylesheet">
  <link rel="stylesheet" type="text/css" href="../dist/style.css"/>
  <title>Homework 1</title>
</head>
<body>
<div class="container-header mx-auto">
  <header>
    <nav class="navbar navbar-expand-lg navbar navbar-light bg-light">
      <a class="navbar-brand pr-4"
         href="https://github.com/TrekFuel/home_tasks_FE-2" target="_blank"><img
          src="../images/github-logo-header-image.png"
          alt="GitHub" title="GitHub"
          width="40" height="40"/></a>
      <button class="navbar-toggler" type="button" data-toggle="collapse"
              data-target="#navbarSupportedContent"
              aria-controls="navbarSupportedContent" aria-expanded="false"
              aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav mr-auto">
          <li class="nav-item active pr-5">
            <a class="nav-link" href="homework-3.html">Home Tasks (to the
              previous page)<span
                  class="sr-only"></span></a>
          </li>
          <li class="nav-item active">
            <a class="nav-link" href="#2">Contacts<span
                class="sr-only"></span></a>
          </li>
        </ul>
      </div>
    </nav>
  </header>
</div>
<div class="container mx-auto d-flex">
  <main>
    <div class="row mt-5 mb-5 ml-3 mr-3">
      <div class="col">
        <h1 class="text-center mb-4">Notes</h1>
        <div class="input-group input-group-lg mx-auto mt-5 mb-5">
          <input type="text" class="form-control"
                 id="note-value"
                 name="note-value"
                 value=""
                 placeholder="Note"
                 aria-label="Note"
                 aria-describedby="button-addon4 inputGroup-sizing-lg">
          <div class="input-group-append" id="button-addon4">
            <button class="btn btn-outline-secondary" id="add-note"
                    type="button">Add note
            </button>
            <button class="btn btn-outline-secondary" id="remove-note"
                    type="button">Remove
              note
            </button>
          </div>
        </div>
        <div class="alert alert-danger d-none" id="error-message"
             role="alert"></div>
      </div>
    </div>
    <div class="row mt-3 mb-3">
      <div class="col">
        <ul id="list"></ul>
      </div>
    </div>
  </main>
</div>
<div class="container-footer mx-auto">
  <footer>
    <a name="2"></a>
    <div class="card text-center">
      <div class="card-header">
        <a name="7"></a>
        <h3>Contacts</h3>
      </div>
      <div class="card-footer text-center">
        <ul class="list-unstyled p-2">
          <li>
            <a href="https://vk.com/bolotinnikita" target="_blank">
              <img src="../images/vk-logo.png"
                   width="30"
                   height="30"
                   alt="ВК"
                   title="ВК"/></a>
          </li>
          <li>
            <a href="https://twitter.com/bolotinnick" target="_blank">
              <img src="../images/twitter-logo.png"
                   width="30"
                   height="30"
                   alt="Twitter"
                   title="Twitter"/></a>
          </li>
          <li>
            <a href="https://www.linkedin.com/in/bolotinnick/" target="_blank">
              <img src="../images/linkedin-logo.png"
                   width="30"
                   height="30"
                   alt="LinkedIn"
                   title="LinkedIn"/></a>
          </li>
          <li>
            <a href="https://github.com/TrekFuel" target="_blank">
              <img src="../images/github-logo.png"
                   width="30"
                   height="30"
                   alt="GitHub"
                   title="GitHub"/></a>
          </li>
          <li>
            <a href="https://www.instagram.com/bolotinnick/" target="_blank">
              <img src="../images/instagram-logo.png"
                   width="30"
                   height="30"
                   alt="Instagram"
                   title="Instagram"/></a>
          </li>
          <li>
            <a href="mailto:ridge96@yandex.ru?subject=website">
              <img src="../images/email-logo.png"
                   width="30"
                   height="30"
                   alt="Email"
                   title="Email"/></a>
          </li>
          <li>
            <a href="https://t.me/bolotinnick" target="_blank">
              <img src="../images/telegram-logo.png"
                   width="30"
                   height="30"
                   alt="Telegram"
                   title="Telegram"/></a>
          </li>
          <li>
            <a href="skype:nick-spinner96?add">
              <img src="../images/skype-logo.png"
                   width="30"
                   height="30"
                   alt="Skype"
                   title="Skype"/></a>
          </li>
          <li>
            <a href="viber://chat?number=+375291328633">
              <img src="../images/viber-logo.png"
                   width="30"
                   height="30"
                   alt="Viber"
                   title="Viber"/></a>
          </li>
          <li>
            <a href="https://wa.me/375291328633" target="_blank">
              <img src="../images/whatsapp-logo.png"
                   width="30"
                   height="30"
                   alt="WhatsApp"
                   title="WhatsApp"/></a>
          </li>
        </ul>
        <div class="btn btn-info mb-2">Bolotin Nikita &copy;, 2019-2020 <br>
          FE-2
          Courses
        </div>
      </div>
      <div class="text-left m-2">
        <a href="#top" class="btn btn-primary" id="btn">To the top
          &uarr;</a>
      </div>
    </div>
  </footer>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
        integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
        crossorigin="anonymous"></script>
<script
    src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
    integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
    crossorigin="anonymous"></script>
<script
    src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
    integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
    crossorigin="anonymous"></script>
<script src="../js/notes(hw-3).js"></script>
</body>
</html>

// eslint-disable-next-line no-undef
describe('notes(hw-3).js -> initNotesList', () => {
  // eslint-disable-next-line no-undef
  it('should return Object from the LocalStorage in case there are items'
    + ' there, otherwise should return an empty array', () => {

  });
});

1 个答案:

答案 0 :(得分:0)

您到底想测试哪些尚未进行的测试? getNotesListaddItemremoveItem方法已经公开。只需直接测试公开的公共功能即可。这将间接测试所有实施细节。

现在,可能是有些代码无法通过这种方式进行测试,或者测试起来非常尴尬。在这种情况下,您应该重构代码以使其更具可测试性。

例如,initNotesList函数不可直接测试。您可能希望将其公开为一个公共函数(即,将其添加到return语句中)并针对它编写一些单元测试。我还将创建并公开一个clearNotesList函数,以帮助建立和拆除测试。

但是除此之外,没有太多的事情要做。单元测试没有魔力。您只需要创建清晰,简单的代码并公开适当的代码即可简化测试。