【问题标题】:Generate tests based on the result of a promise in Jest JS根据 Jest JS 中的承诺结果生成测试
【发布时间】:2019-01-15 06:33:37
【问题描述】:

现在我有一个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 文件时立即运行,并为每个包含有效文件的文件夹生成一个测试。

但是,我现在需要为数据库中的每条记录生成一个测试。据我所知,大多数提供数据库功能的可用模块都是在 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

正如人们所预料的那样,promise 被创建,但直到 Jest 已经期望从文件中接收测试列表之后才有机会实际触发测试的生成。

我考虑过的一件事是有一个测试,它本身就是一个检查所有报告的承诺,但是它会在第一个导致失败的expect 上失败,我们想要获得所有报告的列表测试失败的报告。我们真正想要的是对每个单独的测试。

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

那里有大量 Jest 资源,搜索后我没有找到任何适用于我的问题的资源,所以如果我以某种方式错过了它,我们深表歉意。

【问题讨论】:

    标签: javascript jestjs


    【解决方案1】:

    好的,在浏览了几天的文档和代码之后,它看起来越来越像这样在 Jest 中根本无法完成(或者更准确地说,这与 Jest 的测试理念背道而驰)。

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

    如果有人能提出更好的解决方案,我会很高兴的。

    【讨论】:

      猜你喜欢
      • 2016-07-23
      • 1970-01-01
      • 2018-10-16
      • 1970-01-01
      • 2018-05-07
      • 2019-03-11
      • 1970-01-01
      • 2017-09-14
      • 2019-06-10
      相关资源
      最近更新 更多