1

I'm new to Jest so I apologise if my questioning doesn't read correctly, I'm unit testing a method on a vanilla JS class that has a reference to the class property 'this.original_params'. From reading the docs and many other Stackoverflow posts, I'm still confused as to what parts I have to mock and the syntax for doing so. I'm currently trying to test for the input value being empty and the destination value coming from this.original_params.

// autocomplete.js
export default class Autocomplete {
constructor(site_config, page_name) {
    this.site_config = site_config;
    this.page_name = page_name;
    this.lat = null;
    this.lng = null;
    this.original_params = '';
}

init() {
    this.original_params = new URLSearchParams(document.querySelector('meta[name="originalParams"]').content);
}

getDestination(inputSelector) {
    if (document.querySelector(inputSelector).getAttribute('value') !== '') {
        return document.querySelector(inputSelector).value;
    }
    console.log(this.original_params.has('destination'));
    if (this.original_params.has('destination')) {
        return this.original_params.get('destination');
    }
  }
}

I have tried multiple ways of writing the test but I fail to understand where to start. Here is the current iteration of the test:

// autocomplete.test.js
it('Sets destination if it exists in Original Params', () => {
    document.body.innerHTML = `<meta name="original_params" content="siteid=62309&amp;currency=USD&amp;cid=ROCK&amp;useMiles=&amp;checkin=11/12/21&amp;pageSize=15&amp;mapSize=13&amp;groupid=43285&amp;radius=5&amp;nights=3&amp;latitude=26.10879170000000&amp;map=&amp;longitude=-80.10643370000000&amp;destination=Austin, TX, USA"><input type="search" id="address-input" placeholder="Destination" value="" required="true">`;

    const original_params = new URLSearchParams(
        '<meta name="original_params" content="siteid=62309&amp;currency=USD&amp;cid=ROCK&amp;useMiles=&amp;checkin=11/12/21&amp;pageSize=15&amp;mapSize=13&amp;groupid=43285&amp;radius=5&amp;nights=3&amp;latitude=26.10879170000000&amp;map=&amp;longitude=-80.10643370000000&amp;destination=Austin, TX, USA"></meta>'
    );

    expect(autocomplete.getDestination('input#address-input')).toEqual('Austin, TX, USA');
});

The error I am getting:

● getDestination › Sets destination if it exists in Original Params

TypeError: this.original_params.has is not a function

  80 |             return document.querySelector(inputSelector).value;
  81 |         }
> 82 |         console.log(this.original_params.has('destination'));
     |                                          ^
  83 |         if (this.original_params.has('destination')) {
  84 |             return this.original_params.get('destination');
  85 |         }

Any help is very much appreciated.

skyboyer
  • 22,209
  • 7
  • 57
  • 64

1 Answers1

0

Few things:

  • You forgot to call the init() on AutoComplete instance
  • In init querySelector looks for meta[name="originalParams"] but in test you have <meta name="original_params"

Changing your tests to this should make it pass:

it('Sets destination if it exists in Original Params', () => {
  document.body.innerHTML = `<meta name="originalParams" content="siteid=62309&amp;currency=USD&amp;cid=ROCK&amp;useMiles=&amp;checkin=11/12/21&amp;pageSize=15&amp;mapSize=13&amp;groupid=43285&amp;radius=5&amp;nights=3&amp;latitude=26.10879170000000&amp;map=&amp;longitude=-80.10643370000000&amp;destination=Austin, TX, USA"><input type="search" id="address-input" placeholder="Destination" value="" required="true">`;
  let autocomplete = new Autocomplete();
  autocomplete.init();

  expect(autocomplete.getDestination('input#address-input')).toEqual('Austin, TX, USA');
});

Also, URLSearchParams only receives the query string part of the URL. So new URLSearchParams('<meta ...>') doesn't work. You have to use the following although it hasn't been used in your test at all:

new URLSearchParams('siteid=62309&amp;currency=USD&amp;cid=ROCK&amp;useMiles=&amp;checkin=11/12/21&amp;pageSize=15&amp;mapSize=13&amp;groupid=43285&amp;radius=5&amp;nights=3&amp;latitude=26.10879170000000&amp;map=&amp;longitude=-80.10643370000000&amp;destination=Austin, TX, USA');
Sam R.
  • 16,027
  • 12
  • 69
  • 122
  • Thank you for your response, while I'm frustrated that my mistakes were seemingly obvious now I look at it, I'm glad it wasn't mock related. One thing I am curious about that you may be able to answer - if I wanted to set the original_params in the constructor, would that then require mocking? Thanks again for your help. – Matt Sartain Dec 07 '20 at 19:53
  • @MattSartain, I don't see a use case for mocking here. `original_params` is set to an empty string in constructor. Then it is updated in `init` function. The `init` function has dependency to `document.querySelector` function. So as long as `querySelector` returns what you want and you are able to provide anything you want, then I don't see why you'd need mocks. – Sam R. Dec 07 '20 at 20:11