Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/449.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何嵌套Jest测试_Javascript_Jestjs - Fatal编程技术网

Javascript 如何嵌套Jest测试

Javascript 如何嵌套Jest测试,javascript,jestjs,Javascript,Jestjs,在这种情况下,我需要创建一个调用函数并检查其返回值的测试。它返回一个对象,所以我必须遍历它并检查大约100个值的正确性。如果其中一个失败了,我想知道是哪一个 我无法用vanillaJest解决如何做到这一点,因为测试是自包含的,并且在失败时会收到有意义的错误消息 例如,我可以这样做:(用伪代码来说明,而不是实际代码) 问题在于,如果值不正确,那么错误消息就没有多大帮助,因为它不会告诉我100个值中哪一个有问题 我无法更改为test.each(),因为我收到一个错误,说我有嵌套的test()调用,

在这种情况下,我需要创建一个调用函数并检查其返回值的测试。它返回一个对象,所以我必须遍历它并检查大约100个值的正确性。如果其中一个失败了,我想知道是哪一个

我无法用vanillaJest解决如何做到这一点,因为测试是自包含的,并且在失败时会收到有意义的错误消息

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

问题在于,如果
正确
,那么错误消息就没有多大帮助,因为它不会告诉我100个值中哪一个有问题

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

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

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.inst
beforeAll()
设置之前,它会失败。(Jest首先运行所有
descripe()
块,然后运行
beforeAll()
,然后运行
test()
。这意味着在
beforeAll()
块创建类实例之前,我首先在
descripe()
块中调用
This.inst.run()


有什么办法可以做到这一点吗?要使一个测试需要在所有子测试之间创建和共享一个对象,一个调用函数以获取该组数据的测试组,然后在该组中进行一系列测试?

是的,可以根据
描述
测试
块的执行顺序:

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);
      });
    }
  });
});

我想出了一个解决办法。这有点老套,但似乎管用。本质上,您使用承诺来包装您感兴趣的值,因此一个测试将坐在那里等待另一个测试的结果

显然,只有当测试并行运行时,或者如果顺序顺序是在等待承诺之前解决承诺,这才有效

下面唯一的技巧是将
wait
放在
beforeAll()
块中,以便该值可用于该
description()
节中的所有测试。这避免了在每个单独的测试中等待

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

这是一个很大的工作,只是因为您无法提供关于
expect()
调用的描述(与其他测试框架不同),但是如果您一直在开玩笑,那么这至少是可行的。希望有一天他们会添加一个per expect描述来避免所有这些

以下是一些示例伪代码:

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);
            });
        }
    });
});

您需要在descripe中声明至少一个测试,在本例中是第一个describe@lissettdm:你能解释一下如何解决这个问题吗?我的真实代码在每个
descripe()
中都有其他测试,为了清楚起见,我只是省略了它们。有没有办法做到
this.inst.run()
也在测试中,这样,如果它抛出异常,我就可以将其视为测试失败?否则它看起来可以工作,我会尝试它,谢谢!
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);
            });
        }
    });
});