繁体   English   中英

如何嵌套 Jest 测试

[英]How to nest Jest tests

我有一种情况,我需要创建一个调用 function 并检查其返回值的测试。 它返回一个 object 所以我必须遍历它并检查 100 个左右的值是否正确。 如果其中一个失败了,我想知道是哪一个。

我无法弄清楚如何使用 vanilla Jest 执行此操作,以便测试是独立的,并且我会在失败时收到有意义的错误消息。

例如,我可以这样做:(伪代码来说明,不是实际代码)

describe('Test for function A', () => {
    beforeAll('Create class instance', () => {
        this.inst = new MyClass();
    });

    test('Call function with no parameters', () => {
        const value = this.inst.run();

        for (each key=value) {
            expect(value).toBe(correct); // on failure, doesn't tell me the key, only the value
        }
    });
});

这样做的问题是,如果valuecorrect ,则错误消息不是很有帮助,因为它没有告诉我 100 个值中的哪个有问题。

我无法更改为test.each()因为我收到一个错误消息,说我有嵌套的test()调用,这是不允许的。

如果我使用内部test()并将父test()更改为describe()则代码变为:

describe('Test for function A', () => {
    beforeAll('Create class instance', () => {
        this.inst = new MyClass();
    });

    describe('Call function with no parameters', () => {
        const value = this.inst.run();

        for (each value) {
            test(`Checking ${value.name}`, () => {
                expect(value).toBe(correct);
            });
        }
    });
});

这会给我一个详细的错误消息,除了this.inst.run()在测试设置期间被调用,在this.instbeforeAll()设置之前,所以它失败了。 (Jest 首先运行所有describe()块,然后beforeAll()test() 。这意味着我首先在describe()块中调用this.inst.run() ,然后beforeAll()块创建 class 实例。 )

有什么方法可以实现吗? 要进行需要在所有子测试之间创建和共享 object 的测试,调用 function 的测试组来获取该组的数据,然后在组内进行一堆测试?

是的,可以根据describetest块的执行顺序:

describe("Test for function A", () => {
  this.inst = new MyClass();
  afterAll("Create class instance", () => { //--> use this instead of beforeAll
    this.inst = new MyClass();
  });

  test("Should be defined", () => {
    //--> at least one test inside describe
    expect(inst).toBeTruthy();
  });

  describe("Call function with no parameters", () => {
    const value = this.inst.run();

    test("Should be defined", () => {
      //--> at least one test inside describe
      expect(value).toBeTruthy();
    });

    for (/*...each value */) {
      test(`Checking ${value.name}`, () => {
        expect(value).toBe(correct);
      });
    }
  });
});

我想出了一个解决方法。 这有点hacky,但它似乎工作。 本质上,您使用承诺来包装您感兴趣的值,因此一个测试将坐在那里await另一个测试的结果。

显然,这仅适用于并行运行测试,或者如果顺序排序使得 promise 在等待之前解决。

下面唯一的技巧是将await放置在beforeAll()块中,以便该值可用于该describe()部分中的所有测试。 这避免了在每个单独的测试中await的需要。

这样做的好处是测试设置(创建对象)在test()中,因此会捕获异常,并且检查本身( expect().toBe() )在单独的测试中,因此测试名称可以是设置为描述性的东西。 否则,如果您的expect()调用在 for 循环中,则当一个失败时,无法确定哪个数组条目有问题。

仅仅因为您无法在expect()调用上提供描述(与其他测试框架不同),这是很多工作,但如果您被 Jest 困住,那么这至少可以工作。 希望有一天他们会添加一个符合预期的描述来避免这一切。

这是一些示例伪代码:

describe('Test for function A', () => {
    let resolveValue;
    let promiseValue = new Promise(resolve => resolveValue = resolve);

    describe('Create class instance', () => {
        test('Run processing', () => {
            this.inst = new MyClass();
            // inst.run() is now called inside a test(), so any failures will be caught.
            const value = this.inst.run();
            resolveValue(value); // release 'await promiseValue' below
        });
    });

    describe('Call function with no parameters', () => {
        let value; // this is global within this describe() so all tests can see it.

        beforeAll(async () => {
            // Wait for the above test to run and populate 'value'.
            value = await promiseValue;
        });

        for (each value) {
            // Check each value inside test() to get a meaningful test name/error message.
            test(`Checking ${value.name}`, () => {
                // 'value' is always valid as test() only runs after beforeAll().
                expect(value).toBe(correct);
            });
        }
    });
});

暂无
暂无

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

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