【问题标题】:jest - run one test-module with different test setup multiple times开玩笑 - 多次使用不同的测试设置运行一个测试模块
【发布时间】:2021-04-23 05:32:33
【问题描述】:

NodeJS 上正在运行一个应用程序。它的架构灵感来自 Oncle Bob 的书:“清洁架构”。一切都很完美,但是: 目前,我们对使用 fake-DB 运行的所有模块进行了单元测试。我们希望以这种方式进行集成测试:使用相同的测试(与我们用于单元测试的测试一样)进行集成测试,但“注入”真实的数据库。 我怎么能用jest 做到这一点?我不想复制所有的单元测试代码并创建代码重复(测试设置除外)。

单元测试实际上是这样的:

const DB = require("FakeDB");
let test_description = "unit-testing with FakeDB";

describe(`${test_description}`, () => {

    let db;

    beforeAll(() => {
        const cnf = create_config("test");
        db = new DB(cnf);
    });

    afterAll( () => {
        db.connection_close();
    });

    test("should save entity to DB", () => {
        try {
            // execute: save entity to DB 
        } catch (err) {
            console.error(err);
        }
    })
})

我如何注入另一个数据库,例如到require("PostgresDB")

【问题讨论】:

    标签: node.js unit-testing testing jestjs integration-testing


    【解决方案1】:

    您首先需要分解设置测试运行对象的代码。完成此操作后,您可以运行两次测试:一次针对假 dB,另一次针对真实 dB。

    这只是我的想法,但它可能是您正在寻找的。不过,您可能可以做更多的清理工作:

    const FakeDB = require("FakeDB")
    const RealDB = require("PostgresDB")
    describe('unit testing with FakeDB', () => {
       let db;
    
        beforeAll(() => {
           const cnf = create_config("test");
            db = new FakeDB(cnf);
        });
    
        afterAll( () => {
            db.connection_close();
        });
    
        test("should save entity to DB", () => {
            myTest(db);
        })
    })
    
    describe('unit testing with RealDB', () => {
       let db;
    
        beforeAll(() => {
            const cnf = create_config("real");
            db = new RealDB(cnf);
        });
    
        afterAll( () => {
            db.connection_close();
        });
    
        test("should save entity to DB", () => {
            myTest(db);
        })
    })
    myTest(db) {
            try {
                // execute: save entity to DB 
            } catch (err) {
                console.error(err);
            }
    }
    

    【讨论】:

    • 对不起,我不知道如何实现你的想法。我提供了一个coden-p;你能提供一些涵盖你想法的代码吗?
    • @Chris 我更新了我的答案。让我知道这是否有助于说明我的观点。
    • 不,抱歉,该解决方案复制每个测试并且每个测试都有代码重复。我想避免这些重复,我正在寻找一种解决方案来阻止我复制每个测试。如果代码是 Java 代码,我会提出以下两个选项: 1. 创建一个抽象 base-testclass 并在每个测试类的每个泛化中注入 DB 或 2. mvn 的用法:stackoverflow.com/a/45262452/7421890。但是我不知道我在 JS 中有哪些可能性或选项?
    • Typescript 确实有抽象类的概念。您可以使用它并更接近您的低代码重复目标。
    • 迟到的答案...非常感谢!我们尝试了很多,得出的结果是对于Node.js,我们不喜欢任何可能的解决方案;)
    【解决方案2】:

    假设我们有两个模块 add.js 和 add_copy.js 具有相同的功能。

    function add (a, b) {
        return a + b
      }
    
    module.exports = {add}
    

    安装dotenvnpm install dotenv

    创建 .evn 文件

    DB=One
    

    虚拟规格文件

    let add;
    if (process.env.DB == "One"){
         add = require('./add.js');
    }
    if (process.env.DB == "Two"){
         add = require('./add_copy.js');
    }
    
    let test_description = "unit-testing with FakeDB";
    
    describe(`${test_description}`, () => {
        
        beforeAll(() => {
          
        });
    
        afterAll( () => {
            
        });
    
        test("some test", () => {
           console.log(add.add(2,3));
    
        })
    })
    

    这个例子的 jest.config.js

    require('dotenv').config();
    module.exports = {
        verbose: true,
      };
    

    这里的 'add' 根据 .evn 文件中提供的 'DB' 值发生变化。

    你也可以试试类似的

    let MyDB;
    if (process.env.DB == "Fake"){
         MyDB= require("FakeDB")
    }
    if (process.env.DB == "Real"){
         MyDB= require("PostgresDB")
    }
    

    【讨论】:

      猜你喜欢
      • 2019-11-10
      • 2020-12-21
      • 1970-01-01
      • 2019-01-07
      • 2021-03-11
      • 2021-06-16
      • 1970-01-01
      • 2021-01-01
      • 1970-01-01
      相关资源
      最近更新 更多