[英]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
}
});
});
这样做的问题是,如果value
不correct
,则错误消息不是很有帮助,因为它没有告诉我 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.inst
被beforeAll()
设置之前,所以它失败了。 (Jest 首先运行所有describe()
块,然后beforeAll()
和test()
。这意味着我首先在describe()
块中调用this.inst.run()
,然后beforeAll()
块创建 class 实例。 )
有什么方法可以实现吗? 要进行需要在所有子测试之间创建和共享 object 的测试,调用 function 的测试组来获取该组的数据,然后在组内进行一堆测试?
是的,可以根据describe
和test
块的执行顺序:
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.