0

I have a function:

function validateClub(club) {
  //.. other validation

  let existingClub
  $http.get('/clubs/fetch/' + club.clubName).then(data => {
    existingClub = data
  }, err => {
    $log.error(err)
  })

  console.log(existingClub)

  if(existingClub) return {result: false, reason: 'Club already exists. Choose another Club Name'}

  return {result: true}
}

and I call it like this:

function createClub(club) {
  let validationResult = validateClub(club)
  console.log(validationResult)
  if (validationResult.result === false) {
    throw new Error('The Club you entered has failed validation reason: ' + validationResult.reason)
  }

  // .. create club logic
}

Where createClub() is called from an Angular controller. I haven't got to writing the controller yet as I'm stuck with the test. I am using ngMocks $httpBackend to fake a response, like this:

describe.only('when creating a new club with an existing clubName', () => {
  it('should throw exception', () => {
    $httpBackend
      .when('GET', '/clubs/fetch/ClubFoo')
      .respond(200, {_id:'1', clubName: 'ClubFoo', owner: 'foo@bar.com'})

    const newClub = {
      clubName: 'ClubFoo',
      owner: 'foo@bar.com',
    }

    dataService.createClub(newClub).then(data => {
      response = data
    })

    $httpBackend.flush()
    // expect(fn).to.throw('The Club Name you have entered already exists')
    // ignore the expect for now, I have changed the code for Stack Overflow
  })
})

console.log(existingClub) is always undefined console.log(validationResult) is always {result: true}

What am I doing wrong? I'm expecting the former to be {_id:'1', clubName: 'ClubFoo', owner: 'foo@bar.com'} and the latter to be {result: false, reason: 'Club already exists. Choose another Club Name'}

Rodders
  • 2,425
  • 2
  • 20
  • 34
  • $http.get returns a promise, doesn't it?. It is probably not resolved yet - when yoo do the little console.log. – madflow Sep 26 '16 at 14:11
  • yes. But it would be resolved if I did the console.log inside the `then` ... right? I tried that. – Rodders Sep 26 '16 at 14:14
  • In order to resolve a promise that you are creating, you have to inject a scope/ or (rootscope) into your test case and kick the next digest cycle with scope.$digest() – Vladimir M Sep 26 '16 at 14:14
  • I could use the $q service? I tried that but I have an idea – Rodders Sep 26 '16 at 14:17
  • Damn, no good. Do you have any info regarding injecting scope into the tests? I shall take a look into that – Rodders Sep 26 '16 at 14:28

1 Answers1

0

It's matter of timing. your $http request doesn't resolved immediately. (i.e. existingClub are undefined and validateClub always return {result: true}).

function validateClub(club) {
  let existingClub

  // make fn return promise
  return $http.get('/clubs/fetch/' + club.clubName).then(data => {
    // update existingClub info when $http req resolved
    existingClub = data
    console.log(existingClub)

    if(existingClub) return {result: false, reason: '...'}
    return {result: true}
  }, err => {
    $log.error(err)
  })
}

also should createClub return promise for dataService.createClub(newClub).then(...)

function createClub(club) {
  return validateClub(club).then(validationResult => {
    console.log(validationResult)
    if (validationResult.result === false) {
      throw new Error('The Club you entered has failed validation reason: ' + validationResult.reason)
    }
    // ...

  })
}
ian park
  • 122
  • 1
  • 8