微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何最好地为 .findAll() 等 Sequelize 函数创建单元测试使用 Mocha、Chai

如何解决如何最好地为 .findAll() 等 Sequelize 函数创建单元测试使用 Mocha、Chai

我参加了一个编程训练营,我们目前正在学习全栈 JavaScript。我们正在使用 Express 框架,我选择使用 sqlite3 数据库。这是在当地社区中心维护书籍的基本应用程序。我最多需要编写 3 个单元测试,而我遇到困难的是 GET / 路由。此路由旨在从数据库提取数据并在您访问根路由时呈现它们以创建当前在数据库中的书籍列表。

我想测试包含 awaited Book.findAll() Sequelize 函数bookList 变量是否实际上正在发送包含行数据到 Pug 模板引擎以呈现书籍列表。

当我在本地托管时,这是按预期工作的。我只是对如何在我的单元测试中反映这一点感到困惑。我附上了包含我所有测试的 routes/index.jsviews/index.pugtest/readOp_test.js包括用于 GET / 路由的测试。如果我需要分享更多代码,请告诉我,并会回复任何愿意帮助我的人需要什么。


readOp_test.js

let chai = require('chai');
let chaiHTTP = require('chai-http');
let chaiPromised = require('chai-as-promised');
let application = require('../app');
let expect = require('chai').expect;
chai.use(chaiHTTP);
chai.use(chaiPromised);
chai.should();

// Unit Test Suite
describe('Unit Tests for Endpoints to meet Code Louisville Project Requirements',() => {
    //Test Spec for READ ALL operation


    
    /* it('should pull data from all rows in the database',(done) => {
        chai.request(application)
            .get('/')
            .end((err,res) => {
                res.body.should.be.a('object');
                done();
            })
    }); */

    //Test Spec for READ-by-id operation
    it('should pull data from the below id',(done) => {
        const id = 2;
        chai.request(application)
            .get(`/${id}`)
            .end((err,res) => {
                res.body.should.be.a('object');
                done();
            })
    });
    it('should return status 404 when READING the below id which is not in the database',(done) => {
        const id = 12;
        chai.request(application)
            .get(`/${id}`)
            .end((err,res) => {
                res.should.have.status(404);
                done();
            })
    });
    //Test Spec for CREATE operation
    it('shouldnt POST the below book entry since the title value is an empty string.',async() => {
        let res = await chai
        .request(application)
        .post('/')
        .type('form')
        .send({title: '',author: "al-Gibber",genre: "Math",language: "arabic"})

        expect(res.status).to.equal(500)
    });
    it('should POST the below book entry since all properties contain actual string values.',async() => {
        let res = await chai
        .request(application)
        .post('/')
        .type('form')
        .send({title: 'Gibberish',language: "arabic"})

        expect(res.status).to.equal(200)
    });
});

routes/index.js

// Requiring Express to enable access to the framework's methods,properties,& other tools.
const express = require('express');
// Router handles HTTP requests.
const router = express.Router();
// These two variables are ensuring `routes/index.js` has access to the database & its models.
const db = require('../db');
const { Book } = db.models;



//This is a convenient function that handles async/await.
function asyncHandler(cb){
    return async(req,res,next) => {
        try {
        await cb(req,next)
        } catch(error){
        // Forward error to the global error handler
        next(error);
        }
    }
}



//This route handles the initial load of the app,the root route,& will draw data from each row in the database & display it on the homepage.
//This route is a READ operation distinctly a READ ALL operation.
router.get('/',asyncHandler(async (req,res) => {
    const bookList = await Book.findAll();
    //The use of .render() method ensures that the `index.pug` template is rendered when user visits the root directory.
    //{ bookList } is an object containing data from each row in the database to be used in the Pug template.
    res.render('index',{bookList});
}));



//This route handles adding a book to the app's database by rendering the newBook.pug template which contains a form to collect the column data for the database.
//This route is the beginning of the CREATE operation for this app.
router.get('/new',(req,res) => {
    res.render('newBook',{ book: {}});
});

//This route handles the data collected by newBook.pug's form. It creates the database entry and posts the data.
//This route is the closure for the CREATE operation for this app.
router.post('/',res) => {
    console.log(req.body);
    let book;
    try {
        book = await Book.create(req.body);
        console.log(book);
        res.redirect('/');
    } catch (error) {
        throw error;
    }
}));



//This route handles rendering found data for each book that would be clicked on in the index.pug template.
//This route is another distinct READ operation that is reading an entry's data based on the primary key ID selected on index.pug.
router.get("/:id",res) => {
    const book = await Book.findByPk(req.params.id);
    if(book) {
      res.render("bookViewing",{ book });  
    } else {
      res.sendStatus(404);
    }
  })); 



//Ensures that all routes written in this folder can be used in the root's `app.js` file.
module.exports = router;

index.pug

doctype html
html(lang="en")
  head
    title Library
    link(rel='stylesheet',href='/static/stylesheets/style.css')
  body
    div#app
      div#container
        h1 Library
        h2 Our Book Selection
        
        each book in bookList
          book
            p
              span= book.title
              | 
              a(href=`/${book.id}`) Learn More

        p This library is open to all in our local community!
        a(href="/new") Add New Book

正确呈现的 index.pug 模板的屏幕截图

Screenshot of rendered PUG template

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。