【问题标题】:Jest - How do I reset object state for each test?Jest - 如何为每个测试重置对象状态?
【发布时间】:2021-03-16 20:14:08
【问题描述】:

我是 Jest 的新手,我正试图弄清楚如何在每次测试后重置测试对象。

当前代码

describe.only('POST request - missing entry', () => {
    // newBlog is the "test" object
    let newBlog = {
        title: 'Test Title',
        author: 'Foo Bar',
        url: 'www.google.com',
        likes: 100
    }

    test('sets "likes" field to 0 when missing', async () => {
        delete newBlog.likes // propagates to next test
        console.log(newBlog)
    })

    test('returns 400 error when "title" and "url" fields are missing', async () => {
        console.log(newBlog)
    })
})

目标:我正在使用 jest 编写测试来测试错误的 POST 请求。即我的 POST 请求会故意为每个测试缺少字段。

likes 字段将从第一个测试中省略,而title, url 字段将在第二个测试中丢失。目标是只编写一次newBlog 对象,而不是为每个测试重写对象。

问题 这里的主要问题是第一个测试的结果会传播到下一个测试,即当删除第一个测试的likes 字段时,它保持不变并开始第二个测试而没有@987654326 @字段。

我想知道如何为每个测试重置对象的内容。

尝试到目前为止,我尝试了几件事:

  1. 我使用BeforeEach以下列方式重置newBlog
beforeEach(() => {
        let newBlog = {
            title: 'Test Title',
            author: 'Foo Bar',
            url: 'www.google.com',
            likes: 100
        }

        return newBlog
    })

但是,上面的代码不起作用,因为newBlog 在不同的范围内,所以每个测试都不能识别newBlog 变量。

  1. 我还使用AfterEach通过以下方式重置:
  afterEach(() => {
        jest.clearAllMocks()
    })

这一次,它运行了,但给了我与第一个代码 sn-p 相同的结果。

我想知道如何为每个测试重置对象,因为 stackoverflow 中讨论的许多解决方案似乎都专注于重置 functions 而不是 objects

提前感谢您的帮助。

【问题讨论】:

  • 声明你的beforeEachnewBlog变量otuside
  • @DanielA.White 谢谢,这正是我所需要的!

标签: javascript testing jestjs


【解决方案1】:

试试这样,在 describe 中声明变量并在 beforeEach 中重置它:

describe.only('POST request - missing entry', () => {
// newBlog is the "test" object
let newBlog;

beforeEach(() => {
    newBlog = {
         title: 'Test Title',
         author: 'Foo Bar',
         url: 'www.google.com',
         likes: 100
    }

}}

test('sets "likes" field to 0 when missing', async () => {
    delete newBlog.likes // propagates to next test
    console.log(newBlog)
})

test('returns 400 error when "title" and "url" fields are missing', async () => {
    console.log(newBlog)
})
})

【讨论】:

    【解决方案2】:

    您需要使用 Jest 的 beforeEach() 函数是正确的;然而,唯一可以从 beforeEach() 返回的东西是承诺和生成器——从 beforeEach() 返回 newBlog 什么都不做。我要做的是在 describe 函数中创建一个局部变量,并在每次测试运行之前让 beforeEach() 重新分配该变量,如下所示。

    fdescribe('POST request - missing entry', () => {
      let newBlog;
    
      beforeEach(() => {
        newBlog = {
          title: 'Test Title',
          author: 'Foo Bar',
          url: 'www.google.com',
          likes: 100
        }
      });
    
      test('sets "likes" field to 0 when missing', async () => { 
        delete newBlog.likes; // remove likes key from copied object
        console.log(newBlog);
      });
    
      test('returns 400 error when "title" and "url" fields are missing', async () => {
        delete newBlog.title;
        delete newBlog.url;
        console.log(newBlog);
      });
    })
    

    此外,jest.clearAllMocks() 会清除模拟 函数 的所有调用和实例,这不会以您在此处使用的方式重置 newBlog 变量。

    【讨论】:

      【解决方案3】:

      我通常在这种情况下对测试对象进行深度复制。所以我有一个辅助函数(你也可以使用 Lodash 的 deepClone 函数)

      const deepCopy = (obj: Object) => JSON.parse(JSON.stringify(obj));
      

      在您的测试中,您创建所需测试对象的新深层副本,而不是像这样改变它的状态:

      test('sets "likes" field to 0 when missing', async () => {
        let testObj = deepCopy(newBlog)  
        delete testObj.likes // propagates to next test
        console.log(testObj)
      })
      

      【讨论】:

        猜你喜欢
        • 2015-01-30
        • 1970-01-01
        • 2019-04-01
        • 2021-01-06
        • 1970-01-01
        • 2022-11-12
        • 2014-05-04
        • 2023-01-10
        • 2018-08-09
        相关资源
        最近更新 更多