最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Jest - How do I reset object state for each test? - Stack Overflow

programmeradmin2浏览0评论

I am new to Jest, and I am trying to figure out how to to reset the test object after each test.

Current Code

describe.only('POST request - missing entry', () => {
    // newBlog is the "test" object
    let newBlog = {
        title: 'Test Title',
        author: 'Foo Bar',
        url: 'www.google',
        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)
    })
})

Objective: I am writing test using jest to test for bad POST request. i.e. my POST request will intentionally have missing fields for each test.

likes field will be omitted from first test while title, url field will be missing from second test. Goal is to write newBlog object only once rather than rewriting objects for each tests.

Problem Main issue here is that the result of first test propagates to next test, i.e. when removing likes field for first test, it stays like that and starts the second test without having likes field.

I want to know how I can reset the content of object for each test.

Attempts So far, I tried few things:

  1. I used BeforeEach to reset the newBlog in following manner:
beforeEach(() => {
        let newBlog = {
            title: 'Test Title',
            author: 'Foo Bar',
            url: 'www.google',
            likes: 100
        }

        return newBlog
    })

However, above code does not work since newBlog is in different scope so each test does not recognize newBlog variable.

  1. I also used AfterEach to reset in following manner:
  afterEach(() => {
        jest.clearAllMocks()
    })

This time, it ran but gave me the same results as first code snippet.

I would like to know how to reset objects for each test as many of the solution discussed in stackoverflow seems to focus on resetting functions rather than objects.

Thank you for your help in advance.

I am new to Jest, and I am trying to figure out how to to reset the test object after each test.

Current Code

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

Objective: I am writing test using jest to test for bad POST request. i.e. my POST request will intentionally have missing fields for each test.

likes field will be omitted from first test while title, url field will be missing from second test. Goal is to write newBlog object only once rather than rewriting objects for each tests.

Problem Main issue here is that the result of first test propagates to next test, i.e. when removing likes field for first test, it stays like that and starts the second test without having likes field.

I want to know how I can reset the content of object for each test.

Attempts So far, I tried few things:

  1. I used BeforeEach to reset the newBlog in following manner:
beforeEach(() => {
        let newBlog = {
            title: 'Test Title',
            author: 'Foo Bar',
            url: 'www.google.com',
            likes: 100
        }

        return newBlog
    })

However, above code does not work since newBlog is in different scope so each test does not recognize newBlog variable.

  1. I also used AfterEach to reset in following manner:
  afterEach(() => {
        jest.clearAllMocks()
    })

This time, it ran but gave me the same results as first code snippet.

I would like to know how to reset objects for each test as many of the solution discussed in stackoverflow seems to focus on resetting functions rather than objects.

Thank you for your help in advance.

Share Improve this question edited Oct 17, 2020 at 12:26 skyboyer 23.7k7 gold badges61 silver badges71 bronze badges asked Oct 16, 2020 at 23:43 selfPointerselfPointer 3491 gold badge2 silver badges14 bronze badges 2
  • 1 declare the newBlog variable otuside of your beforeEach – Daniel A. White Commented Oct 16, 2020 at 23:44
  • @DanielA.White Thanks, that's what I needed! – selfPointer Commented Oct 17, 2020 at 0:02
Add a comment  | 

3 Answers 3

Reset to default 12

Try something like this, declare the variable in the describe and reset it in the 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)
})
})

You were correct in needing to use Jest's beforeEach() function; however, the only things that are returnable from beforeEach() are promises and generators—returning newBlog from beforeEach() does nothing. What I would do is create a local variable in the describe function and have beforeEach() reassign that variable before each test runs as seen below.

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

Additionally, jest.clearAllMocks() clears all calls and instances of a mocked function which will not reset the newBlog variable in the way you want to use it here.

I usually deep copy the test object in this kind of scenarios. So I have a helper function (you can use e.g. Lodash's deepClone function too)

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

In your tests you create a new deep copy of the wanted test object instead of mutating it's state like this:

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

评论列表(0)

  1. 暂无评论