根据Jest JS中Promise的结果生成测试

时间:2018-10-31 22:39:20

标签: javascript jestjs

现在我有一个simple.test.js文件,它基于简化的呼叫/响应文件生成对test的调用(因此我们不需要为每个简化的文件都写.test.js案例)。作为参考,我将在此处添加文件:

'use strict';

const api = require('./api');

const SCRIPT_NAME_KEY = Symbol('script name key'),
    fs = require('fs'),
    path = require('path');

const generateTests = (dir) => {
    const relPath = path.relative(__dirname, dir);
    let query, resultScripts = [], resultSqls = [];
    for (let entry of fs.readdirSync(dir)) {
        if (entry[0] === '-')
            continue;
        let fqEntry = path.join(dir, entry);
        if (fs.statSync(fqEntry).isDirectory()) {
            generateTests(fqEntry);
            continue;
        }
        if (entry === 'query.json')
            query = fqEntry;
        else if (entry.endsWith('.sql'))
            resultSqls.push(fqEntry);
        else if (entry.endsWith('.js') && !entry.endsWith('.test.js'))
            resultScripts.push(fqEntry);
    }
    if (!query && resultScripts.length === 0 && resultSqls.length === 0)
        return;
    if (!query)
        throw `${relPath} contains result script(s)/sql(s) but no query.json`;
    if (resultScripts.length === 0 && resultSqls.length === 0)
        throw `${relPath} contains a query.json file but no result script(s)/sql(s)`;

    try {
        query = require(query);
    } catch (ex) {
        throw `${relPath} query.json could not be parsed`;
    }

    for (let x = 0; x < resultScripts.length; x++) {
        let scriptName = path.basename(resultScripts[x]);
        console.log('scriptName', scriptName);
        try {
            resultScripts[x] = require(resultScripts[x]);
        } catch (ex) {
            throw `${relPath} result script ${scriptName} could not be parsed`;
        }
        resultScripts[x][SCRIPT_NAME_KEY] = scriptName;
    }

    test(`ST:${relPath}`, () => api.getSqls(query).then(resp => {
        if (resultScripts.length === 0) {
            expect(resp.err).toBeFalsy();
            expect(resp.data).toBeAllValidSql();
        } else {
            for (const script of resultScripts)
                expect({ n: script[SCRIPT_NAME_KEY], r: script(resp, script[SCRIPT_NAME_KEY]) }).toPass();
        }

        for (const sql of resultSqls)
            expect(resp.data).toIncludeSql(fs.readFileSync(sql, 'utf8'));
    }));
};

expect.extend({
    toPass(actual) {
        const pass = actual.r === void 0 || actual.r === null || !!actual.r.pass;
        return {
            pass: pass,
            message: pass ? null : () => actual.r.message || `${actual.n} check failed!`
        }
    }
});

generateTests(path.join(__dirname, 'SimpleTests'));

这真的很棒! Jest加载.test.js文件后,它将立即运行,并为包含有效文件的每个文件夹生成一个测试。

但是,我现在需要为数据库中的每条记录生成一个测试。据我所知,提供DB功能的大多数可用模块都是在promise的前提下工作的(合理地说是这样!)。因此,现在我需要等待查询返回后再生成测试。

这是我正在尝试的:

'use strict';

const api = require('./api');

api.getAllReportsThroughSideChannel().then((reports) => {
    for (const report of reports) {
        test(`${report.Name} (${report.Id} - ${report.OwnerUsername})`, () => {
            // ...
        });
    }
});

但是当我这样做时,我得到:

 FAIL  ./reports.test.js
  ● Test suite failed to run

    Your test suite must contain at least one test.

      at ../node_modules/jest/node_modules/jest-cli/build/TestScheduler.js:256:22

正如人们可能期望的那样,将创建诺言,但是直到Jest已经期望从文件中接收到测试列表之后,才有机会真正触发测试的生成。

我考虑的一件事是进行一个测试,该测试本身就是一个可以检查所有报告的承诺,但是随后在第一个expect上失败并导致失败,我们想获取一个列表所有未通过测试的报告。我们真正想要的是对每个对象进行单独的测试。

我想我最终想知道的问题是,世代的测试是否有可能通过promise(而不是测试本身)来完成。

有很多关于Jest的资源,搜索后我没有找到任何适用于我的问题的东西,如果我因某种原因错过了它,就深表歉意。

1 个答案:

答案 0 :(得分:0)

好吧,经过几天的文档和代码检查,看起来越来越像Jest无法做到的(或者更正确地说,这与Jest的测试哲学背道而驰)。

因此,我在运行jest运行时之前已经创建了一个步骤,该步骤只是将查询结果下载到文件中,然后使用该文件同步生成测试用例。

如果有人可以提出更好的解决方案,我会喜欢的。