0

I want to set up a request once and then use it in multiple tests. This was the best way I could come up to do that, but it seems odd to have to have to declare req mutable just so it will be available in an outside scope.

describe('GET /password', () => {
  let req
  before(() => {
    req = chai.request(app).get('/password')
    return req
  })

  it('should get the password page', () => {
    return req.then(res => res.should.have.status(200))
  })

  describe('The password page', () => {
    it('should render HTML', () => {
      return req.then(res => res.should.be.html)
    })
  })
})

I was hoping I could do something like

const req = before(() => {
  return chai.request(app).get('password')
})

... but it seems that before() does not return the value returned in its callback.

Is there a better (more "elegant") way to do this?

Michael Dorst
  • 8,210
  • 11
  • 44
  • 71
  • I think for the async get call you will have to use the done callback in before() function.. This will make sure that the api req is completed and result stored in the varible before any of test cases executes. – damitj07 Nov 27 '19 at 06:17
  • @damitj07 According to something I read, in newer versions of Mocha, if you return a promise in `before()`, the promise is guaranteed to resolve before the tests are run. Please correct me if I'm wrong. – Michael Dorst Nov 28 '19 at 09:09
  • I guess, this article says so. https://stackoverflow.com/questions/24723374/async-function-in-mocha-before-is-alway-finished-before-it-spec maybe try and test it out that way. – damitj07 Nov 28 '19 at 09:13

2 Answers2

1

You can simply use a function returning a promise:

describe('GET /password', () => {

   function getPassword () {
      return chai.request(app).get('/password')
   }

   it('should get the password page', () => {
      return getPassword()
         .then(res => res.should.have.status(200))
         .catch(err => err.should.not.exist)
   })

   describe('The password page', () => {
      it('should render HTML', () => {
         return getPassword()
            .then(res => res.should.be.html)
            .catch(err => err.should.not.exist)
      })
   })

})

I find using a function also much more readable than using before which is not visible at first look.

alexloehr
  • 1,773
  • 1
  • 20
  • 18
  • I like this solution. However it makes two separate requests. That is fine in this case, but might not be ideal in other cases. Maybe using an IIFE you could get around that. – Michael Dorst Dec 03 '19 at 20:36
0

In my previous experience, I usually stored the response in a variable then in each test, I accessed that variable. Seems that your case is only care about response so this solution below may fit.

describe('GET /password', () => {
  let response; // create a variable

  before(() => {
    return chai.request(app).get('/password') // add `return` here for promise
      .then(res => {
        response = res; // store response from api to the variable
      })    
  })

  it('should get the password page', () => {
    response.should.have.status(200);
  })

  describe('The password page', () => {
    it('should render HTML', () => {
      response.should.be.html
    })
  })
})

Having the variable as mutable is not odd in my opinion.

Hope it helps

deerawan
  • 8,002
  • 5
  • 42
  • 51