Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 单元测试和集成测试_Node.js_Unit Testing_Express_Testing_Mocha.js - Fatal编程技术网

Node.js 单元测试和集成测试

Node.js 单元测试和集成测试,node.js,unit-testing,express,testing,mocha.js,Node.js,Unit Testing,Express,Testing,Mocha.js,我目前正在开发一个nodejs/expressrestapi(个人项目),我想从这个项目中学到尽可能多的东西 因此,在我的项目中,我使用了sequelize作为ORM层,我有一个名为'bus'的模型,我为这个模型构建了CRUD端点 现在我想对我开发的这个模型/api进行一些测试,我阅读了一些关于测试的教程,发现有多种类型的测试分为两大类:白盒和黑盒 因此,我编写了一些测试api的集成测试(集成测试是黑盒测试) 我想知道如何编写一些单元测试,但我不知道要测试什么,bus模型是一个Sequelize

我目前正在开发一个nodejs/expressrestapi(个人项目),我想从这个项目中学到尽可能多的东西

因此,在我的项目中,我使用了
sequelize
作为
ORM
层,我有一个名为'bus'的模型,我为这个模型构建了CRUD端点

现在我想对我开发的这个模型/api进行一些测试,我阅读了一些关于测试的教程,发现有多种类型的测试分为两大类:白盒和黑盒

因此,我编写了一些测试api的集成测试(集成测试是黑盒测试)

我想知道如何编写一些单元测试,但我不知道要测试什么,
bus
模型是一个Sequelize模型,所以我要测试的所有东西都已经在
Sequelize
库中进行了测试。api端点的测试是通过集成测试完成的

PS:这是我第一次写测试

我正在使用以下技术:
nodejs
sequelize
express
mocha
chai

公交车型号定义

const Sequelize = require('sequelize');

module.exports = function(sequelize) {

    let Bus =  sequelize.define('bus', {
        name: {
            type: Sequelize.STRING,
        },
    });


    Bus.associate = function(models) {
        Bus.hasOne(models.LaneBus, {
            foreignKey: 'busId'
        });
    };

    return Bus;
} 
总线Api端点测试

const request = require('superagent');
const expect = require('chai').expect;

const app = require('../../src/app');
var http = require('http');

const models = require('../../src/models');


describe("bus", function () {

    var bus_id;

    it('should create bus', function (done) {

        request.post('http://localhost:3000/bus')
            .type('form')
            .send({
                name: 'bus_test_1',
            }).set('Accept', 'application/json')
            .set('Authorization', global.JWT_TOKEN_TEST_ADMIN)
            .end((err, res) => {
                expect(res.status).to.be.eq(201, 'invalid return code');
                expect(res.body.status).to.be.eq('success', 'invalid retun status');

                bus_id = res.body.id;

                done();
            })
    });

    it('should get list of bus', function (done) {

        request.get('http://localhost:3000/bus')
            .set('Accept', 'application/json')
            .end((err, res) => {
                expect(res.status).to.be.eq(200, 'invalid return code');
                expect(res.body.metadata).to.not.be.undefined

                done();
            })
    });


    it('should modify bus', function (done) {

        request.put(`http://localhost:3000/bus/${bus_id}`)
            .type('form')
            .send({
                name: 'bus_test_2'
            })
            .set('Authorization', global.JWT_TOKEN_TEST_ADMIN)
            .end((err, res) => {
                expect(res.status).to.be.eq(200, 'invalid return code');
                expect(res.body.status).to.be.eq('success', 'invalid retun status');
                done();
            });
    });

    it('modify bus should get error because bus dont exists', function (done) {

        request.put(`http://localhost:3000/bus/aaa`)
            .type('form')
            .send({
                name: 'bus_test_2'
            })
            .set('Authorization', global.JWT_TOKEN_TEST_ADMIN)
            .end((err, res) => {
                expect(res.status).to.be.eq(404, 'invalid return code');
                expect(res.body.status).to.be.eq('failure', 'invalid return code');
                done();
            });
    });


    it('should get bus', function (done) {

        request.get(`http://localhost:3000/bus/${bus_id}`)
            .end((err, res) => {
                expect(res.status).to.be.eq(200, 'invalid return code');
                expect(res.body.name).to.be.eq('bus_test_2');
                done();
            });
    });

    it('get bus should return error because bus dont exist', function (done) {

        request.get(`http://localhost:3000/bus/aaaa`)
            .end((err, res) => {
                expect(res.status).to.be.eq(404, 'invalid return code');
                expect(res.body.status).to.be.eq('failure', 'invalid return code');
                done();
            });
    });



    it('user role cannot create bus', function (done) {
        request.post('http://localhost:3000/bus')
            .type('form')
            .send({
                name: 'bus_test_1',
            }).set('Accept', 'application/json')
            .set('Authorization', global.JWT_TOKEN_TEST_USER)
            .end((err, res) => {
                expect(res.body.status).to.be.eq('failure', 'invalid retun status');


                done();
            })
    })

    it('user role cannot modify bus', function (done) {
        request.put(`http://localhost:3000/bus/${bus_id}`)
            .type('form')
            .send({
                name: 'bus_test_2'
            })
            .set('Authorization', global.JWT_TOKEN_TEST_USER)
            .end((err, res) => {
                expect(res.body.status).to.be.eq('failure', 'invalid retun status');
                done();
            });
    })


    it('user role cannot delete bus', function (done) {
        request.delete(`http://localhost:3000/bus/${bus_id}`)
            .set('Authorization', global.JWT_TOKEN_TEST_USER)
            .end((err, res) => {
                expect(res.body.status).to.be.eq('failure', 'invalid return code');
                done();
            });
    })


    it('should delete bus', function (done) {

        request.delete(`http://localhost:3000/bus/${bus_id}`)
            .set('Authorization', global.JWT_TOKEN_TEST_ADMIN)
            .end((err, res) => {
                expect(res.status).to.be.eq(200, 'invalid return code');
                done();
            });
    });

    it('delete bus should get error because bus dont exist', function (done) {

        request.delete(`http://localhost:3000/bus/${bus_id}`)
            .set('Authorization', global.JWT_TOKEN_TEST_ADMIN)
            .end((err, res) => {
                expect(res.status).to.be.eq(404, 'invalid return code');
                expect(res.body.status).to.be.eq('failure', 'invalid return code');
                done();
            });
    });





});

不明确的需求/异常使代码难以测试。有时候,你只是不知道什么会破坏你的代码。这种情况在现实世界中经常发生。你不知道什么会破坏你的密码;否则,你就把它修好了

在任何情况下,我建议使用代码覆盖率进行测试,例如。确保您的代码至少经过80%的测试。稍后,当您更新代码或修复bug时,您可以看到哪些未被测试,并添加相应的测试

  • 集成(黑盒)测试:我建议 集成测试,因为它提供了一种用于定义特性的简单语言,并且可以测试端到端特性,而不仅仅是API端点。例如:

    Feature: Simple maths
     In order to do maths
     As a developer
     I want to increment variables
    
  • 白盒单元测试:Mocha&Chai很好,所以您可以继续进行这些测试,但我要添加stub和mock。因此,您可以将上面的测试转换为集成测试(想想类似的事情),或者用Sinon将它们转换为单元测试


  • 这些是我的建议,但请随便看看,选择您最喜欢的库进行测试。只需确保区分集成测试和单元测试

    这就是我所做的:),我想知道一件简单的事情,如果一些函数/操作测试数据库连接或一些复杂的依赖关系,最好使用集成测试来测试它,对吗?单元测试用于简单的功能,理想情况下,通过单元测试,然后开始集成测试。在大型项目中,当需求和设计是可靠的(这需要时间),功能是直接的和可测试的时,就需要进行单元测试。1) 单元测试是关于应用程序的;2) 集成测试是关于系统的;3) 相比之下,集成测试需要花费更多的时间和资源。你在这里说的是用真正的数据库连接进行单元测试。当我们急于发布项目时,它变得越来越普遍。许多CI都支持它。不过,如果可能的话,我还是建议大家按照课本上的内容去做。这关乎质量和态度。