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?
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 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.
How do I access the current model? I am aware of application.__container_.lookup but I understand this is a bit of a hack.
import Ember from 'ember';
import { module, test } from 'qunit';
import startApp from 'myapp/tests/helpers/start-app';
let application;
module('Acceptance | booking/edit', {
beforeEach: function() {
application = startApp();
},
afterEach: function() {
Ember.run(application, 'destroy');
}
});
test('visiting /booking/edit', function(assert) {
visit('/booking/1');
//At this point I would like to access the model returned from the route model hook.
andThen(function() {
assert.equal(currentURL(), '/booking/1');
});
});
Sample Route excerpt.
this.route('booking', { path:'/booking' }, function() {
this.route('edit', { path:'/:booking_id' }, function() {
this.route('account', { path:'/account' });
...
});
...
});
You should be able to use moduleFor and then within the test you can use this.subject() to access the controller.
moduleFor('controller:bookingsEdit', 'Bookings Edit Controller');
If moduleFor is undefined. Then import moduleFor import {moduleFor} from 'ember-qunit';
and then within the test you can use this.subject() to access the controller
moduleFor(fullName [, description [, callbacks]])
fullName: (String) - The full name of the unit, ie
controller:application, route:index.
description: (String) optional - The description of the module
callbacks: (Object) optional - Normal QUnit callbacks (setup and
teardown), with addition to needs, which allows you specify the other
units the tests will need.
http://guides.emberjs.com/v1.10.0/testing/testing-controllers/
https://github.com/rwjblue/ember-qunit
I am using ember-cli 0.2.6 and ember-cli-simple-auth 0.8.0-beta.2.
Starting from scratch I do the following:
ember create project1
//inside project1
ember install ember-cli-simple-auth
now i am adding the following line to tests/helpers/start-app:
import 'simple-auth-testing/test-helpers';
and in environment.js only add this:
if (environment === 'test') {
ENV['simple-auth'] = {
store: 'simple-auth-session-store:ephemeral'
};
...
}
Also I created an acceptance test named "login"
ember generate acceptance-test login
Which i adjusted to make use of the authenticateSession(); helper:
import Ember from 'ember';
import {
module,
test
} from 'qunit';
import startApp from 'project1/tests/helpers/start-app';
var application;
module('Acceptance: Login', {
beforeEach: function() {
application = startApp();
},
afterEach: function() {
Ember.run(application, 'destroy');
}
});
test('visiting /login', function(assert) {
authenticateSession();
ok('yes');
});
Now however, whenever i run ember test I get the same error message:
acceptance/login-test.js: line 22, col 3, 'authenticateSession' is not defined.
What did I miss to be not able to access the simple-auth helpers inside my acceptance test? I also tried with the simple-auth 0.7.3 release,... In another try I set up a custom authorizer, but got the same error.
You need to import the testing helpers like this:
import initializeTestHelpers from 'simple-auth-testing/test-helpers';
initializeTestHelpers();
I am trying to include a module in my app from one of the tests. Is it even possible to do that? I am only able to include a module in the 'tests' directory.
I keep getting the infamous "Could not find module" error.
http://localhost:4200/assets/test-support.js:5578:16: Could not find module d3graph/app/controllers/index imported from d3graph/tests/unit/utils/graph-helper-test
This is my test code:
import { moduleFor, test } from 'ember-qunit';
import Ember from 'ember';
import helper from '../../../app/anything/anywhere'; // <- THIS LINE FAILS
moduleFor('util:graph-helper', 'Graph Helper', {
beforeEach: () => initialize()
});
function initialize() { /* something */ };
test('test desc', function(assert) {
var testObj = this.subject();
// test logic follows
});
I did try various modifications of the path to the module, including absolute path from root, I even tried including via 'require()', but alas without success.
Please help.
Shouldn't be a problem. You will need a needs line inside your moduleFor call:
import { moduleFor, test } from 'ember-qunit';
import Ember from 'ember';
moduleFor('util:graph-helper', 'Graph Helper', {
needs: ['controller:index'],
beforeEach: () => initialize()
});
function initialize() { /* something */ };
test('test desc', function(assert) {
var testObj = this.subject();
// test logic follows
});
See http://guides.emberjs.com/v1.10.0/testing/testing-controllers/#toc_testing-controller-needs for more details about needs.
Edit
Disregard the above information... that's for Ember modules which resolve the standard way. To include modules off the beaten Ember path, a simple ES6 import will suffice (this example demonstrates pulling in some-util for the controller:index unit tests):
import { moduleFor, test } from 'ember-qunit';
import Ember from 'ember';
import SomeUsefulUtil from '<application-name>/utils/some-useful-util';
moduleFor('controller:index', 'Graph Helper', {
beforeEach: () => initialize()
});
function initialize() { /* something */ };
test('test desc', function(assert) {
var testObj = this.subject();
// Create utility class instance
var someUsefulUtilInstance = new SomeUsefulUtil();
// test logic follows
});
The potentially non-intuitive part of this is that you have to prefix the import with your application's name instead of the standard app directory.