I have a component that calls something like:
this.get('store')
.findAll('calendar-event')
.then((data) => {
// do stuff
});
However, when I replace findAll() with query() it breaks my integration testing.
this.get('store')
.query('calendar-event', { some_stuff: [596] })
.then((data) => {
// do stuff
});
The application in the web browser via ember server continues to function correctly. However: no luck with integration testing. Error I get is: TypeError: Cannot read property 'setObjects' of null
Integration test looks like:
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import moment from 'moment';
import startMirage from '../../helpers/setup-mirage-for-integration';
moduleForComponent('main-calendar', 'Integration | Component | main calendar', {
integration: true,
beforeEach() {
startMirage(this.container);
},
afterEach() {
window.server.shutdown();
}
});
test('it renders', function (assert) {
this.render(hbs`{{main-calendar}}`);
assert.equal(this.$('.col-sm.text-center').text().trim(), moment().format('MMMM YYYY'));
});
Any ideas why it would render with the server but not on the integration testing side of things.
Related
I have just begun adding ember-intl into an application for which I had working tests. My acceptance tests are still working, but my integration tests on components whose templates are using ember-intl for string translation are failing with:
"No locale defined. Unable to resolve translation:..."
In the ember-intl docs there is a section on Integration Testing, which seems to be out of date:
import hbs from 'htmlbars-inline-precompile';
import wait from 'ember-test-helpers/wait';
import { moduleForComponent, test } from 'ember-qunit';
let service;
moduleForComponent('x-product', 'XProductComponent', {
integration: true,
setup() {
service = this.container.lookup('service:intl');
service.setLocale('en-us');
}
});
test('it renders', function(assert) {
assert.expect(1);
this.render(hbs`{{x-product price=price deadline=deadline}}`);
this.set('price', 1000);
this.set('deadline', new Date());
let output = this.$().text();
assert.ok(output);
});
test('it translates', function(assert) {
assert.expect(1);
/* waits for async behavior (loading translations on app boot) to settle */
return wait().then(() => {
assert.equal(service.t('some.key'), 'Hello world');
});
});
I've looked in the Ember docs and I can see how to stub a service for testing, but not how to just load the service in a test and then work with it.
Instead of using this.container, we now need to use this.owner in the new format tests. Here's a snippet of code showing how to use it in context:
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { find, render } from '#ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
module('Integration | Component | login-form', function(hooks) {
setupRenderingTest(hooks);
let service;
hooks.beforeEach(function() {
service = this.owner.lookup('service:intl');
service.setLocale('en-us');
});
test('it renders', async function(assert) {
await render(hbs`{{login-form}}`);
assert.equal(find('[data-test-login-title]').textContent.trim(), 'Login');
});
});
A PR has been submitted to ember-intl, so hopefully the docs will reflect the latest best-practice soon.
I've been struggling with mirage for the past few days, and still haven't come up with a solution.
Even with a very simplified configuration (see below), mirage responds with a 404 error code whenever it is called within acceptance tests.
The calls do work perfectly when I serve my app and look at the browser console
(Mirage responds with a 200 status, and the data is here with the hello#world.com that I setup bellow).
Here's my mirage/config.js file
// mirage/config.js
export default function() {
this.get('/users', function() {
return {
data: [{
type: 'user',
id: 'first',
attributes: {
email: 'hello#world.com'
}
}]
};
});
}
Here's my app/routes/home.js
// app/routes/home.js
import Route from '#ember/routing/route';
export default Route.extend({
model() { return this.store.findAll('user'); }
});
Here's the failing test
import { module, test } from 'qunit';
import { visit, currentURL } from '#ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
module('Acceptance | home', function(hooks) {
setupApplicationTest(hooks);
test('visiting /home', async function(assert) {
await visit('/home');
assert.equal(currentURL(), '/home');
});
});
With this message:
Promise rejected during "visiting /home": Ember Data Request GET /users
returned a 404
Payload (Empty Content-Type)
Not found: /users# 152 ms
Source:
Error: Ember Data Request GET /users returned a 404
Payload (Empty Content-Type)
Not found: /users
at ErrorClass.EmberError
(http://localhost:7357/assets/vendor.js:24125:25)
at ErrorClass.AdapterError
(http://localhost:7357/assets/vendor.js:157167:15)
at new ErrorClass (http://localhost:7357/assets/vendor.js:157185:22)
at Class.handleResponse
(http://localhost:7357/assets/vendor.js:169227:18)
at ajaxError (http://localhost:7357/assets/vendor.js:169720:25)
at Class.hash.error
(http://localhost:7357/assets/vendor.js:169308:23)
at fire (http://localhost:7357/assets/vendor.js:3607:31)
at Object.fireWith [as rejectWith]
(http://localhost:7357/assets/vendor.js:3737:7)
at done (http://localhost:7357/assets/vendor.js:9646:14)
at XMLHttpRequest.<anonymous>
(http://localhost:7357/assets/vendor.js:9887:9)
Thank you
Are you sure Mirage is even running during your test?
If you're on a recent version of Ember, Mirage's default initializer may not be running. (This needs to be fixed.)
You might want to give the latest release notes a read, and make sure you're on version 0.4.2+.
In the new style of tests, you'll need to do something like
import { module, test } from 'qunit';
import { visit, currentURL } from '#ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
+ import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
module('Acceptance | login', function(hooks) {
setupApplicationTest(hooks);
+ setupMirage(hooks);
test('visiting /login', async function(assert) {
await visit('/login');
assert.equal(currentURL(), '/login');
});
});
I have a ember js controller with the following action that takes a model.
How do I write a unit test to test the action which returns a promise?
deleteUser(model)
{
model.destroyRecord().then(() => this.transitionToRoute('posts'));
}
The wait() function sounds like what you want here. Not sure it works with promises, as it does not mention promises in this part of the documentation. Might want to give it a shot anyway.
From the Ember docs (https://guides.emberjs.com/v2.12.0/testing/testing-components/):
import { moduleForComponent, test } from 'ember-qunit';
import wait from 'ember-test-helpers/wait';
import hbs from 'htmlbars-inline-precompile';
moduleForComponent('delayed-typeahead', 'Integration | Component | delayed typeahead', {
integration: true
});
const stubResults = [
{ name: 'result 1' },
{ name: 'result 2' }
];
test('should render results after typing a term', function(assert) {
assert.expect(2);
this.set('results', []);
this.set('fetchResults', (value) => {
assert.equal(value, 'test', 'fetch closure action called with search value');
this.set('results', stubResults);
});
this.render(hbs`{{delayed-typeahead fetchResults=fetchResults results=results}}`);
this.$('input').val('test');
this.$('input').trigger('keyup');
return wait().then(() => {
assert.equal(this.$('.result').length, 2, 'two results rendered');
});
});
EDIT: The example above is from integration tests... not sure this is what you have in mind. Note, there is also the andThen helper which you may want to look into. Perhaps give us some more information regarding what you have in mind?
I'm looking at the ember testing guides and it says to do the following when you want to stub out a service
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import Ember from 'ember';
//Stub location service
const locationStub = Ember.Service.extend({
city: 'New York',
country: 'USA',
currentLocation: {
x: 1234,
y: 5678
},
getCurrentCity() {
return this.get('city');
},
getCurrentCountry() {
return this.get('country');
}
});
moduleForComponent('location-indicator', 'Integration | Component | location indicator', {
integration: true,
beforeEach: function () {
this.register('service:location-service', locationStub);
this.inject.service('location-service', { as: 'location' });
}
});
The issue is that I get a Uncaught TypeError: this.register is not a function when I use this code. So I am assuming the in the before each this.register('service:location-service', locationStub); is causing the problem.
Any one has any idea how I can work around this or what's the more proper way of stubbing out a service? This code is currently in Ember's docs.
Looks like this.register is only present on later versions of ember-qunit, you need to make sure you are running ember-qunit >= 0.4.13.
this.register is only present on ember-qunit >= 0.4.13.
http://discuss.emberjs.com/t/service-injection-in-component-integration-tests/8956/3
Looking over the Ember CLI docs, it says to create an integration test like so:
import Ember from "ember";
import { module, test } from 'ember-qunit';
import startApp from '../helpers/start-app';
var App;
module('An Integration test', {
beforeEach: function() {
App = startApp();
},
afterEach: function() {
Ember.run(App, App.destroy);
}
});
test("Page contents", function(assert) {
assert.expect(2);
visit('/foos').then(function() {
assert.equal(find('.foos-list').length, 1, "Page contains list of models");
assert.equal(find('.foos-list .foo-item').length, 5, "List contains expected number of models");
});
});
The problem is, this code results in:
TypeError: undefined is not a function
If I remove the test, I still get that error. If I remove the module, then I don't get the error. (But neither does qunit run the test.) This makes sense, because it looks like ember-qunit doesn't export a module.
So what am I suppose to do here?