[英]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.