jeudi 29 octobre 2015

Stubbing service injected in initializer for testing components in Ember 2.1

Before currentUser was injected as a service in auth-button view model.

{{#if currentUser.loggedIn}}
  {{#link-to 'auth.logout'}}{{t 'auth.logout'}}{{/link-to}}
{{else}}
  {{#link-to 'auth.login'}}{{t 'auth.signIn'}}{{/link-to}}
{{/if}}

export default Ember.Component.extend({
  currentUser: Ember.inject.service('current-user'),
});

With this setup, I could mock currentUser in auth-button test:

import Ember from 'ember';
import hbs from 'htmlbars-inline-precompile';
import { moduleForComponent, test } from 'ember-qunit';
import instanceInitializer from 'ntfrontend/instance-initializers/ember-intl';

const userStub = Ember.Service.extend({
  loggedIn: false,
});

moduleForComponent('auth-button', 'Integration | Component | auth button', {
  integration: true,
  setup() {
    this.register('service:current-user', userStub);
    this.inject.service('current-user', { as: 'currentUser' });
    instanceInitializer.initialize(this);
    const intl = this.container.lookup('service:intl');
    intl.setLocale('en-us');
  }
});

test('should render auth links', function(assert) {
  assert.expect(2);
  this.render(hbs`{{auth/auth-button}}`);
  assert.equal(this.$().text().trim(), 'Sign In');

  this.set('currentUser.loggedIn', true);
  this.render(hbs`{{auth/auth-button}}`);
  assert.equal(this.$().text().trim(), 'Logout');
});

As I need to have access to currentUser in many places, currentUser is now injected in initializer:

export function initialize(App) {
  App.inject('component', 'currentUser', 'service:current-user');
  App.inject('route', 'currentUser', 'service:current-user');
  App.inject('controller', 'currentUser', 'service:current-user');
}

export default {
  name: 'current-user',
  initialize: initialize,
};

With this setup the second case fails (view is not rerendered):

test('should render auth links', function(assert) {
  // actually the stub is not needed as `currentUser` defaults to falsy value

  this.set('user.loggedIn', true); 
  this.render(hbs`{{auth/auth-button}}`);
  assert.equal(this.$().text().trim(), 'Logout'); // still `Sign In`
});

How to go about this kind of dependency injection? Should I manually inject it into App namespace?




Aucun commentaire:

Enregistrer un commentaire