Jest -如何为每个测试重置对象状态?

368yc8dk  于 2023-02-01  发布在  Jest
关注(0)|答案(3)|浏览(171)

我是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字段时,它保持原样,并在没有likes字段的情况下开始第二个测试。

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

尝试到目前为止,我尝试了几种方法:

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()
    })

这一次,它运行了,但给我的结果与第一个代码片段相同。
我想知道如何为每个测试重置对象,因为stackoverflow中讨论的许多解决方案似乎都侧重于重置 * 函数 * 而不是 * 对象 *。
先谢谢你的帮助。

cqoc49vn

cqoc49vn1#

尝试类似这样的操作,在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)
})
})
wqsoz72f

wqsoz72f2#

您需要使用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()清除所有的调用和一个mocked function 的示例,这个 function 不会按照您想要的方式重置newBlog变量。

whhtz7ly

whhtz7ly3#

在这种情况下,我通常会深度复制测试对象,所以我有一个helper函数(你也可以使用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)
})

相关问题