使用 Jest 为 vanilla JS 编写测试

时间:2020-12-29 22:42:16

标签: javascript testing jestjs

我遵循 Dev Eds course 创建待办事项列表,但现在我想编写一些测试来测试代码。我想使用 Jest,但我不知道如何编写测试以确保待办事项被创建和删除

我在下面添加了 app.js 文件(还有 html/css 文件)。我尝试编写测试是在 app.js 文件下。

//Selectors
const todoInput = document.querySelector('.todo-input');
const todoButton = document.querySelector('.todo-button');
const todoList = document.querySelector('.todo-list');
const filterOption = document.querySelector('.filter-todo');

//Event Listeners
todoButton.addEventListener('click', addTodo);
todoList.addEventListener('click', deleteCheck);
filterOption.addEventListener('change', filterTodo);

//Functions
function addTodo(event){
    //console.log(event.target);
    // prevent form from submitting
    event.preventDefault();
    const todoDiv = document.createElement("div");
    todoDiv.classList.add("todo");
    //create LI
    const newTodo = document.createElement('li');
    newTodo.innerText = todoInput.value;
    newTodo.classList.add('todo-item');
    todoDiv.appendChild(newTodo);
    // Checkmark button
    const completedButton = document.createElement('button');
    completedButton.innerHTML = '<i class="fas fa-check"></i>'
    completedButton.classList.add("complete-btn");
    todoDiv.appendChild(completedButton);
    // Delete button
    const deleteButton = document.createElement('button');
    deleteButton.innerHTML = '<i class="fas fa-trash"></i>'
    deleteButton.classList.add("delete-btn");
    todoDiv.appendChild(deleteButton);
    // Append to list
    todoList.appendChild(todoDiv);
    // clear todo input value
    todoInput.value = "";
}

function deleteCheck(e){
    //console.log(e.target);
    const item = e.target;
    if(item.classList[0] === 'delete-btn'){
        const todo = item.parentElement;
        // animation
        todo.classList.add("fall");
        todo.addEventListener("transitionend", function() {
            todo.remove();
        });
    }
    // check mark
    if(item.classList[0] === "complete-btn"){
        const todo = item.parentElement;
        todo.classList.toggle('completed');
    }
}

function filterTodo(e) {
    const todos = todoList.childNodes;
    todos.forEach(function(todo) {
      switch (e.target.value) {
        case "all":
          todo.style.display = "flex";
          break;
        case "completed":
          if (todo.classList.contains("completed")) {
            todo.style.display = "flex";
          } else {
            todo.style.display = "none";
          }
          break;
        case "uncompleted":
          if (!todo.classList.contains("completed")) {
            todo.style.display = "flex";
          } else {
            todo.style.display = "none";
          }
      }
    });
  }

我创建的第一个测试是检查是否创建了待办事项

const todo = require('./app')

test('add a todo', () => {
    expect(todo("buy milk".toBe("buy milk")))
})

但是测试失败了。

1 个答案:

答案 0 :(得分:1)

首先,您需要决定是测试 UI 还是 UI 环绕的系统/引擎。除了 ) 之后缺少的 todo("buy milk" 之外,您正在尝试测试引擎而不是 UI。

在您的情况下,您应该考虑将实际的引擎代码与 UI 层分开。然后就可以测试CRUD了。

让我们举一个基本的例子:

    const Todo = function() {
        let list = [];
        let items = {};
        return {
            create: function(task) { 
                let id = Date.now();
                items[id] = { id, task };
                list.push(id);
                return id;
            },
            read: function(id) {
                return items[id];
            },
            readAll: function() {
                return list.map(id => items[id]);
            },
            delete: function(id) {
                list = list.filter(itemId => itemId !== id);
                delete items[id];
                return true;
            }
        }
    }

这是一个可测试的待办事项引擎,测试看起来像这样(使用 mocha 和 chai):


const { expect } = require("chai");
const Todo = require("./Todo.js"); // replace with your file

describe("Todo", function() {
    const todo = Todo();
    it("should create a todo item and return an ID", function() {
        let id = todo.create("My first todo");
        expect(id).to.be.a("integer");
    });
    it("should create a todo item with text 'My second todo'", function() {
        let id = todo.create("My second todo");
        let text = todo.read(id);
        expect(text).to.equal("My second todo");
    });
    it("should return an array with two todo items", function() {
        let items = todo.readAll();
        // you can also test for exact strings
        expect(items.length).to.equal(2);
    });
    it("should delete first item", function() {
        let items = todo.readAll();
        let id = items[0].id;
        todo.delete(id);
        items = todo.readAll();
        expect(items.length).to.equal(1);
    });
});

进行前端测试时,您将使用 CypressPuppeteer 之类的工具