dar
dar

Reputation: 43

Unit testing sessionStorage value in emberJS

I'm new to ember and trying to figure out how to unit test, using sinon, the sessionStorage based on url parameters when that page is visited. I've tried a few things but still can't get the desired result. It passes even if I change the 'sessionValue' without editing the query param. Thank you in advance.

ember component

beforeModel(transition) {

    //transition will contain an object containing a query parameter. '?userid=1234' and is set in the sessionStorage.

    if(transition.queryparam.hasOwnProperty('userid')){
        sessionStorage.setItem('user:id', transition.queryparam)
    }
}

Ember test

test('Session Storage contains query param value', async assert => {
let sessionKey = "user:id";
let sessionValue = "1234"

let store = {};
  const mockLocalStorage = {
    getItem: (key) => {
      return key in store ? store[key] : null;
    },
    setItem: (key, value) => {
      store[key] = `${value}`;
    },
    clear: () => {
      store = {};
    }
  };

  asserts.expect(1);
  
  let spy = sinon.spy(sessionStorage, "setItem");
  spy.calledWith(mockLocalStorage.setItem);

  let stub = sinon.stub(sessionStorage, "getItem");
  stub.calledWith(mockLocalStorage.getItem);
  stub.returns(sessionValue);

  await visit('/page?userid=1234');
     
  mockLocalStorage.setItem(sessionKey, sessionValue);
  assert.equal(mockLocalStorage.getItem(sessionKey), sessionValue, 'storage contains value');
})

Upvotes: 0

Views: 221

Answers (1)

NullVoxPopuli
NullVoxPopuli

Reputation: 65183

Welcome to Ember!

There are many ways to test, and the below suggestion is one way (how I would approach interacting with the SessionStorage).

Instead of re-creating the SessionStorage API in your test, how do you feel about using a pre-made proxy around the Session Storage? (ie: "Don't mock what you don't own")

Using: https://github.com/CrowdStrike/ember-browser-services/#sessionstorage

Your app code would look like:

@service('browser/session-storage') sessionStorage;

beforeModel(transition) {
  // ... details omitted ...
  // note the addition of `this` -- the apis are entirely the same
  //     as SessionStorage
  this.sessionStorage.setItem('user:id', ...)
}

then in your test:

module('Scenario Name', function (hooks) {
  setupApplicationTest(hooks);
  setupBrowserFakes(hooks, { sessionStorage: true });

  test('Session Storage contains query param value', async assert => {
    let sessionKey = "user:id";
    let sessionValue = "1234"

    let sessionStorage = this.owner.lookup('browser/session-storage');

    await visit('/page?userid=1234');
     
    assert.equal(sessionStorage.getItem(sessionKey), '1234', 'storage contains value');
  });

})

With this approach, sinon isn't even needed :)

Upvotes: 0

Related Questions