jest: 如何在单个测试后进行拆卸(teardown)

31

jest 提供了 afterEachbeforeEachafterAllbeforeAll 来完成设置和拆卸逻辑。我想做的是在一个特定的测试之后清理工作。考虑以下内容:

describe("a family of tests it makes sense to group together", () => {
    ...
    test("something I want to test", () => {
        // some setup needed for just this test
        global.foo = "bar"
        
        // the test
        expect(myTest()).toBe(true)

        // clear up
        delete global.foo
    }
    ...
}

上述问题的问题

如果上面的测试由于某种原因失败,则永远不会运行delete global.foo。这意味着可能随后的所有测试都会失败。与其看到1个测试失败,我看到了一堆测试失败,这可能会让人感到困惑。

潜在(非理想)解决方案

一个解决方案是只需将delete global.foo添加到我的afterEach中。它不需要在每个测试后运行,但也不会造成任何损害。另一个解决方案是将特定的测试单独放置,以便afterEach仅适用于它。但这似乎也不是理想的 - 如果该测试属于其他测试,那么它应该可以保留在其中。

我的问题:

有没有办法仅对特定测试运行拆卸逻辑(而不在实际测试内运行)? 在我的特定用例中,第一种解决方案很好,但我可以想象可能需要更精细的控制的情况。例如,如果我的拆卸方法需要很长时间,我不想重复多次,因为这会减慢整个测试套件的速度。

2个回答

20

在许多情况下,即使只有一个测试需要进行清理,测试也可以共享常见的afterEach清理,只要它不影响其他测试。

否则,这就是块结构的责任。一个或多个测试可以用嵌套的describe分组,以便拥有自己的afterEach等块,唯一的缺点是它会使报告显得不太美观:

describe("a family of tests it makes sense to group together", () => {
    ...
    describe("something I want to test", () => {
        beforeEach(() => {
            global.foo = "bar"
        });
   
        test("something I want to test", () => {
            expect(myTest()).toBe(true)
        }

        afterEach(() => {    
            delete global.foo
        });
    });

beforeEachafterEach可以转换为try..finally

test("something I want to test", () => {
    try {
        global.foo = "bar"
        
        expect(myTest()).toBe(true)
    } finally {
        delete global.foo
    }
})

这也允许进行异步测试,但需要使用async编写,而不是done


1
我发现嵌套的describe方法比try..finally块更好,因为当finally块中的代码失败时,测试也会失败,但是当afterEach或afterAll中的代码失败时,测试仍然可以通过。 - Mehmet Egemen Albayrak

5

我知道这是一个老问题,但是对于未来遇到这个挑战的任何人,这里有一个我很久以前写的小型库,叫做jest-after-this,可以做到这一点:

import { afterThis } from 'jest-after-this';

it('should do something that requires a cleanup', () => {
  global.foo = 'something';
  afterThis(() => {
    delete global.foo;
  });

  // ... rest of test here can fail, the cleanup method will run anyways
});

希望这能帮到你 :)

1
尽管npm页面上没有指向GitHub源代码的链接,但npm网站允许检查已发布的库是否存在恶意软件,并且它看起来很不错。赞 @illberoy! - Jiří Brabec
不错的解决方案!我也很惊讶没有看到 GitHub 链接。@illBeRoy,您能否更新 npm 页面?对于任何感兴趣的人:https://github.com/illBeRoy/jest-after-this - Wilco Waaijer
这应该是jest npm包的一部分。不幸的是,它似乎掉进了漏洞中:https://github.com/jestjs/jest/issues/9305 - Steven

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接