简体   繁体   English

Jest:在测试文件之间共享变量

[英]Jest: Share Variables Between Test Files

I'll start with an example of how I set up my tests for a backend server.我将从一个示例开始,说明如何为后端服务器设置测试。 TL;DR at bottom . TL;底部的博士。

This file represents my server:该文件代表我的服务器:

//server.js
const express = require('express');

class BackendServer {
    constructor(backingFileDestination, database) {
        this.server = express();
        /* Set up server ... */
        /* Set up a mysql connection ... */
    }

    closeMySQLConnectionPool = () => {
        /* Close the mysql connection ... */
    };
}

module.exports = BackendServer;

In my package.json , I have the following:在我的package.json中,我有以下内容:

"jest": {
  "testEnvironment": "node",
  "setupFilesAfterEnv": [
    "<rootDir>/tests/setupTests.js"
  ]
}

Which allows me to use this setup file for my tests:这使我可以使用此设置文件进行测试:

//setupTests.js
const { endpointNames } = require('../../src/common/endpointNames.js');
const BackendServer = require('../server.js');
const server = new BackendServer(
    '../backing_files_test/',
    'test',
);
const supertester = require('supertest')(server.server);

// drop, recreate, and populate the database once before any tests run
beforeAll(async () => {
    await supertester.post(endpointNames.DROP_ALL_TABLES);
    await supertester.post(endpointNames.CREATE_ALL_TABLES);
    await supertester.post(endpointNames.POPULATE_ALL_TABLES);
});

// clean up the local setupTests server instance after all the tests are done
afterAll(async () => {
    await server.closeMySQLConnectionPool();
});

Notice how I had to import the BackendServer class and instantiate it, then use that instance of it.请注意我必须如何导入BackendServer class 并实例化它,然后使用它的那个实例。

Now, I have other test files, for example test1.test.js :现在,我有其他测试文件,例如test1.test.js

//test1.test.js
const { endpointNames } = require('../../src/common/endpointNames.js');
const BackendServer = require('../server.js');
const server = new BackendServer(
    '../backing_files_test/',
    'test',
);
const supertester = require('supertest')(server.server);

// clean up the local server instance after all tests are done
afterAll(async () => {
    await server.closeMySQLConnectionPool();
});

test('blah blah', () => {
    /* Some test ... */
});

The problem is when I go to write test2.test.js , it will be the same as test1.test.js .问题是当我 go 编写test2.test.js时,它将与test1.test.js相同。 This is the issue.这就是问题所在。 For every test file, I need to instantiate a new server and then have a separate afterAll() call that cleans up that server's SQL connection.对于每个测试文件,我需要实例化一个新服务器,然后进行单独的afterAll()调用来清理该服务器的 SQL 连接。 I can't stick that afterAll() inside of setupTests.js because it needs to operate on test1.test.js 's local server instance.我不能将afterAll()放在setupTests.js中,因为它需要在test1.test.js的本地server实例上运行。

TL;DR : Each of my test files instantiates a new instance of my server. TL;DR :我的每个测试文件都实例化了我的服务器的一个新实例。 What I want is to instantiate the server once in setupTests.js and then simply use that instance in all my tests.我想要的是在setupTests.js中实例化一次服务器,然后在我的所有测试中简单地使用该实例。 Is there a good way to share this single instance between all my test files?有没有一种好方法可以在我所有的测试文件之间共享这个单一实例?

I was able to figure out a way to achieve what I wanted.我能够想出一种方法来实现我想要的。 It involves instantiating variables in setupTests.js and then exporting getters for them.它涉及在setupTests.js中实例化变量,然后为它们导出 getter。

//setupTests.js
const { endpointNames } = require('../../src/common/endpointNames.js');
const BackendServer = require('../server.js');
const server = new BackendServer(
    '../backing_files_test/',
    'test',
);
const supertester = require('supertest')(server.server);

// drop, recreate, and populate the database once before any tests run
beforeAll(async () => {
    await supertester.post(endpointNames.DROP_ALL_TABLES);
    await supertester.post(endpointNames.CREATE_ALL_TABLES);
    await supertester.post(endpointNames.POPULATE_ALL_TABLES);
});

// clean up the local setupTests server instance after all the tests are done
afterAll(async () => {
    await server.closeMySQLConnectionPool();
});

const getServer = () => { //        <==== ADD THESE 2 FUNCTIONS
    return server;
};

const getSupertester = () => { //   <==== ADD THESE 2 FUNCTIONS
    return supertester;
};

module.exports = { getServer, getSupertester }; //   <==== EXPORT THEM

I added a couple functions to the end of setupTests.js that, when called, will return whatever the local variables point to at the time.我在setupTests.js的末尾添加了几个函数,调用时将返回局部变量当时指向的任何内容。 In this case, server and supertester are declared with const , so I could have exported them directly I think, but in other cases I had some variables that I wanted to share that were declared with let , so I left it this way.在这种情况下, serversupertester是用const声明的,所以我认为我可以直接导出它们,但在其他情况下,我有一些我想共享的变量是用let声明的,所以我就这样离开了。

Now I have functions exported from setupTests.js that I can import in my test files like this:现在我有从setupTests.js导出的函数,我可以像这样在我的测试文件中导入它们:

//test1.test.js
const { endpointNames } = require('../../src/common/endpointNames.js');
const { getServer, getSupertester } = require('./setupTests.js');

test('blah blah', () => {
    /* Some test using getSupertester().post() or getServer().someFunction() ... */
});

So now I can have local variables inside setupTests.js that are accessible in my .test.js files.所以现在我可以在setupTests.js中使用局部变量,这些变量可以在我的.test.js文件中访问。

This makes my whole testing process cleaner because I only need to set up and tear down one server, which means only 1 connection pool for my SQL server and less code duplication of having to instantiate and clean up a new server in every .test.js file.这使我的整个测试过程更干净,因为我只需要设置和拆除一台服务器,这意味着我的 SQL 服务器只有 1 个连接池,并且减少了必须在每个.test.js中实例化和清理新服务器的代码重复文件。

Cheers.干杯。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM