简体   繁体   中英

Testing document.createElement('a') with Mocha/Chai/Sinon

I am trying to test the following function

export const checkForDuplicateUrl = (containers, url) => {
  let a = document.createElement('a')
  a.href = url
  const urlHostName = a.hostname

  return containers.find((container) => {
    let b = document.createElement('a')
    b.href = container.url
    return urlHostName === b.hostname
  })
}

This function takes in an array of containers and a given url. Should the hostname of the url match the hostname of any of the individual containers , I want to return that container. This method works fine, but I'm not sure how to test this, or indeed even if I should. I wrote a test that initially looked like this:

describe('#checkForDuplicateUrl', () => {    
    const containers = [
      { id: 4, url: 'https://www.party.com'},
      { id: 5, url: 'elainebenes.com'}
    ]
    let url
    describe('when there is a duplicate container and the passed in are the same', () => {
      url = 'www.party.com'
      it('returns the container', () => {
        expect(checkForDuplicateUrl(containers, url).id).to.equal(4)
      })
    })
    describe('when there is a duplicate container and the passed in are the same hostname but one lacks www', () => {
      url = 'party.com'
      it('returns the container', () => {
        expect(checkForDuplicateUrl(containers, url).id).to.equal(4)
      })
    })
    describe('when there is a duplicate container and the passed in are the same hostname but one has https', () => {
      url = 'www.party.com'
      it('returns the container', () => {
        expect(checkForDuplicateUrl(containers, url).id).to.equal(4)
      })
    })
  })

The problem is, that when I run this in my testing environment, document.createElement('a') is always going to have localhost as it's hostname, so it doesn't really matter what I pass in.

If I try to stub the document.createElement() out with sinon, then I'm not really testing anything since I will have to manually return the hostname every time.

Should I even test this function? If so, how should I test it?

First of all, I think your test cases look good and I think this is definitely something worth testing. It's absolutely fine (and recommended in a lot of cases) to stub out external objects/functions for unit testing.

What I do find very confusing is your used of document.createElement() to obtain the hostname from a url. I would try using a dedicated library like url-parse .

var URL = require('url-parse');
var url = new URL('http://www.google.com')
console.log(url.hostname); // 'google'

I'm not entirely sure what you're passing to checkForDuplicateUrl() but I think this gets around the localhost issue.

The problem here was related to the fact that url I was passing into the function was not prepended with http . When you try to set an href on an a tag without http , the a tag just grabs whatever your current location is, which in this case was http://localhost .

This test will pass after changing url = 'www.party.com' to url = 'http://www.party.com'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM