In Open Event Frontend, we have used services like ‘auth-manager’, ‘l10n’, ‘loader’, ‘sanitizer’, etc to ease our work with the help of predefined-functions in those services. However, while dealing with an issue in the project, there was a need to use ‘Routing’ as a service.
In the issue, we wanted to generate an access link dynamically from the access code entered by the user. The format of the access link was as follows:
“base_url + event_id + access_code”
So, for the above URL, we needed to have ‘event_id’ and ‘access_code’.
The ‘access_code’ can be readily accessed from the user’s input itself, whereas to get the event_id, we used the ‘Routing’ service in Ember.
Generally to use a service in Ember, it has to be written first,then registered, injected and then used.
‘Routing’ service in Ember is an inbuilt service unlike the ones listed at the beginning.
There is no need to write it. It can be simply registered, injected and used.
this.register('service:routing', routingStub);
this.inject.service('routing', { as: 'routing' });
where ‘register’ and ‘inject’ are the methods on Ember objects.
The integration tests in Open Event Frontend are written such that the services can be used without injecting, but the tests will fail. To pass those tests, we had to register and inject the service in the required component.
The Routing service could thus be registered and injected into the specific component( injection in the component’s integration test ) only but for future needs, this service might be needed in any other component too. For this purpose, this service was registered and injected in ‘component-helper.js’.
const routingStub = Service.extend({
router: {
router: {
state: {
params: {
'events.view': {
event_id: 1
}
}
}
},
generate() {
return 'http://dummy-url.com';
}
}
});
export default function(path, name, testCase = null) {
moduleForComponent(path, name, {
integration: true,
beforeEach() {
this.register('service:routing', routingStub);
this.inject.service('routing', { as: 'routing' });
this.register('service:l10n', L10n);
this.inject.service('l10n', { as: 'l10n' });
this.application = startApp();
l10nTestHelper(this);
run(() => fragmentTransformInitializer.initialize(getOwner(this)));
}
}
}
Stubbing a Service: This is a process of faking an app of importing a service when no path is available to import. Stubbing of a service is mainly done when one needs to deal with the testing of the app. In our case, the same is done. We have stubbed the ‘Routing’ service in order to deal with the testing part. It can be seen from the above code that we have generated a ‘routingStub’ which fakes the app while registering the service in the ‘beforeModel’. The next line of code shows the ‘injection’ of service into the app.
Now we are just left with one task i.e to pass ‘routing’ from our integration tests to the component.
test('it renders', function(assert) {
this.render(hbs`{{forms/events/view/create-access-code routing=routing}}`);
assert.ok(this.$().html().trim().includes('Save'));
});
Above code shows the same.
Thus we can stub the services in Ember when any component depends on them.
Resources:
Official Ember guide: https://guides.emberjs.com/v2.1.0/testing/testing-components
Blog by Todd Jordan: http://presentationtier.com/stubbing-services-in-emberjs-integration-tests/