Ember component unit testing inject service defined in initalizer - unit-testing

I am writing a unit test case for my component.
Ember 0.12,
Ember-qunit 0.3.13
Ember-i18n: "4.1.1",
I am initialising this i18n service in via Ember initaliazers, so that i can access i18n serivces as this.i18n.t('some key'). which i am using in my component
some: computed('', {
get(){
this.i18n.t('somekey') + "Test"
}
})
My component unit test for this component fails, because i am not able to inject the i18n service. Please help me in solving it and i tried
needs: ['serivces:i18n'] it wont work because i have initialised via Intializers Issue injecting via initalizer
and the below code also wont work because i am using older version of ember-qunit (Please i don't wont to update to newest version because it affects all other test cases)
this.register('service:user-session', userSession);
this.inject.service('user-session', { as: 'userSession' });
Help me in solving in this issue , if there is a need for more clarity in the question , please do comment. Thanks

Related

Unit testing React click outside component using Jest and react testing library

I found this implementation here but its using enzyme.
Unit testing React click outside component
Adding an event to window does not work either:
window.addEventListener('click', () => {
console.log('click on window');
});
Has anyone came across this issue above using jest and "#testing-library/react"?
as #Giorgio mentioned:
fireEvent.click(document)
//or
userEvent.click(document.body);
I'd like to provide an up-to-date answer which follows the same principle as what #eduardomoroni proposed.
The fireEvent hasn't worked for me and so I've managed to achieve it with the userEvent api.
userEvent.click(document.body);
Also, as typescript complains document cannot be passed to the click event handler. Instead, the body is a better solution.
Argument of type 'Document' is not assignable to parameter of type 'TargetElement'.

ReferenceError: ga is not defined [Ionic 2.2 Unit Testing With Karma]

I'm adding unit tests to an Ionic 2.2.0 app I manage, but my Components crash at test-time when they encounter Google Analytics code. I'm using Ionic's official unit testing example as a basis, and my current progress can be seen on our public repo.
My project uses Google Analytics, which is added to the HTML and downloaded at runtime (because we have different keys for development vs production).
The code that initializes Analytics is in my main.ts, and it sets a global variable ga, which is subsequently available throughout the application.
I'm beginning the tests for the app's first page, which uses Analytics. When I run the tests, I'm met with the following error
Component should be created FAILED
ReferenceError: ga is not defined
at new MyBusesComponent (webpack:///src/pages/my-buses/my-buses.component.ts:33:6 <- karma-test-shim.js:138419:9)
at new Wrapper_MyBusesComponent (/DynamicTestModule/MyBusesComponent/wrapper.ngfactory.js:7:18)
at CompiledTemplate.proxyViewClass.View_MyBusesComponent_Host0.createInternal (/DynamicTestModule/MyBusesComponent/host.ngfactory.js:15:32)
........
This is because main.ts doesn't seem to be loaded or executed, and I assume TestBed is doing that purposefully. It's certainly better that I don't have the actual Google Analytics object, but the Component does need a function called ga.
My question, therefore, is as follows: how can I create Google Analytics' ga variable in my test configuration such that it's passed through to my components at test-time?
I've tried exporting a function from my mocks file and adding it to either the imports or providers arrays in my spec file, but to no avail.
I appreciate any advice! Feel free to check my code at our repo I linked to above and ask any followups you need. Thanks!
You declare the var ga but that is just to make TypeScript happy. At runtime, the ga is made global from some external script. But this script is not included in the test.
What you could do is just add the (mock) function to the window for the tests. You could probably do this in your karma-test-shim.js.
window.ga = function() {}
Or if you wanted to test that the component is calling the function with the correct arguments, you could just add the function separately in each test that uses the function. For example
beforeEach(() => {
(<any>window).ga = jasmine.createSpy('ga');
});
afterEach(() => {
(<any>window).ga = undefined;
})
Then in your test
it('..', () => {
const fixture = TestBed.creatComponent(MyBusesComponent);
expect(window.ga.calls.allArgs()).toEqual([
['set', 'page', '/my-buses.html'],
['send', 'pageview']
]);
})
Since you're making multiple calls to ga in the constructor, the Spy.calls will get the argument of all each call and put them in separate arrays.

Ember helper unit test - inject or mock service

I'm on Ember 1.13 (not 2.x yet), and I need to be able to run a helper unit test. My helper has a line:
const i18n = Frontend.__container__.lookup('service:i18n');
which injects a service the ugly way, since before Ember 2.x helpers are not "real" objects and cannot do something like:
i18n: Ember.inject.service('i18n')
When I try to run simple unit tests for the helper, I get:
Can't find variable: Frontend
How do I import/inject/mock the global app namespace in this case? Or is there another way to get past this?

Ember/emberfire run loop acceptance test

So my acceptance test keeps on destroying itself before my promise finishes. I'm aware that I need to wrap my promise in Ember run loop but I just can't get it to work. Here's how my component looks:
export default Ember.Component.extend({
store: Ember.inject.service(),
didReceiveAttrs() {
this.handleSearchQueryChange();
},
/**
* Search based on the searchQuery
*/
handleSearchQueryChange() {
this.get('store').query('animals', {
orderBy: 'name',
startAt: this.attrs.searchQuery
}).then(searchResults => {
this.set('searchResults', searchResults);
});
}
});
I've already tried wrapping this.handleSearchQueryChange(), this.get('store').query... and this.set('searchResults', searchResults) in a run loop but still, the acceptance test just doesn't wait for store.query to finish.
One thing to note that this store query performs a request on a live Firebase back-end.
I'm currently using Pretender to mock the data and solve this issue. But I'd like to solve it through Ember.run as well. Anyone care to provide a solution?
It sounds like your problem may have the same cause as the errors I've been seeing
tl;dr
To work around this issue, I've been using a custom test waiter. You can install it with ember install ember-cli-test-model-waiter (for Ember v2.0+) and it should just make your test work without any further setup (if not, please file a bug).
Longer answer:
The root cause of this problem is that the ember testing system doesn't know how to handle Firebase's asynchronicity. With most adapters, this isn't a problem, because the testing system instruments AJAX calls and ensures they have completed before proceeding, but this doesn't work with Firebase's websockets communication.
The custom test waiter I mentioned above works by waiting for all models to resolve before proceeding with the test, and so should work with any non-AJAX adapter.

How do enable the format.js helpers in Ember Unit tests

I am using Ember with formatjs to internationalize my application, and ember-cli to build it all.
When I generate a component with
ember g component some-component
Ember also creates a test that checks that the component renders. However, if I use the intl-get helper from formatjs in the component template, the unit test fails.
So how can I register the custom helpers that formatjs creates for a unit test?
I first tried to add the intl-get helper:
moduleForComponent('some-component', {
needs: ['helper:intl-get']
});
However, this just fails inside intl-get when it tries to access "intl:main". I would like for the intl initializer to run, but I am not sure if there is even application setup. Or is it some way to just mock those methods using sinon?
My current workaround is to just delete the 'it renders' tests. But I would like for these tests to pass as well, so I can further test rendering later if I want.
Try:
moduleForComponent('some-component', {
integration: true
});