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