3

I have read and followed EmberJS Service Injection for Unit Tests (Ember QUnit) but I'm still not able to figure where the problem is.

I would like to test if my authentication is working as expected. I have written authenticator for ember-simple-auth and session is injected into route. Code itself is working without any issues.

export default Ember.Route.extend({
  authManager: Ember.inject.service('session'),
  ...
  (in actions):
    this.get('authManager').invalidate()

Now, I want to create a test which will test if my authentication is working as I expect. So I wish to use authManager directly.

moduleFor('route:index', 'Unit | Route | xyz', {
  needs: ['service:session']
});

test('2', function(assert) {
  let route = this.subject();
  let s = route.get('authManager');

When I print the content of 's', I get ''. If I change this to something else, then response is undefined as can be expected. Problem is when I want to obtain property 'isAuthenticated' or run 'invalidate()'. In these cases I got 'undefined'. What am I doing wrong?

Community
  • 1
  • 1
Marek Grác
  • 743
  • 9
  • 24
  • My guess is that you need to use integration tests for such purposes. If you want to write unit tests, you need to mock everything but the tested object itself (in this case the index route). I had a similar problem testing services: http://stackoverflow.com/questions/37190648/injecting-service-into-a-mixin-ember2-3 – Pavol May 19 '16 at 19:44

2 Answers2

4

As of Ember 2.13, the correct solution to this is to use this.register:

test('my test', function(assert) {
  this.register('service:session', Ember.Service.extend({
    /* mock code */
  }));

  let subject = this.subject();

  // test code goes here...
}
Jouke van der Maas
  • 4,117
  • 2
  • 28
  • 35
1

In a unit test, we prefer to use mock objects instead of services. In integration tests, we may use real services instead of mocks.

To mock a service, in a unit test:

var stubMyService = Ember.Object.extend({
    //This is a mock object, write a code to test component/route!
    invalidate: function() {
        return 'invalidateCalled';
    },
    isAuthenticated: function(){
       return true;
    }
});

To inject this mock object to your component/route use this.subject() creation as following:

test('2', function(assert){
    var component = this.subject({
        authManager: stubMyService.create()
    });
    ...
});
ykaragol
  • 6,139
  • 3
  • 29
  • 56
  • Thanks for response, very likely I was not clear enough. I wish to test the injected service. Communication of this service is mocked by ember-mirage so there are no other dependencies. Those are the reasons why mocking up service won't help me. I know that I can create a route and use acceptance test withouth bothering with such issues but I would like to know. – Marek Grác May 20 '16 at 14:27
  • Thanks for the response. This has worked for me on a unit-test for a service also (a service injected a service in my case!) – morhook Jan 25 '17 at 15:24
  • This no longer works as of Ember 2.13, see this RFC: https://github.com/emberjs/rfcs/blob/master/text/0150-factory-for.md – Jouke van der Maas May 12 '17 at 08:44