Search code examples
ember.jstddintegration-testingember-testing

How to do Ember integration testing for route transitions?


I'm having a problem doing integration testing with ember using Toran Billup's TDD guide.

I'm using Karma as my test runner with Qunit and Phantom JS.

I'm sure half of if has to do with my beginner's knowledge of the Ember runloop. My question is 2 parts:

1) How do I wrap a vist() test into the run loop properly?

2) How can I test for transitions? The index route ('/') should transition into a resource route called 'projects.index'.

module("Projects Integration Test:", {
  setup: function() {
    Ember.run(App, App.advanceReadiness);
  },
  teardown: function() {
    App.reset();
  }
});

test('Index Route Page', function(){
    expect(1);
    App.reset();    
        visit("/").then(function(){
            ok(exists("*"), "Found HTML");
        });
});

Thanks in advance for any pointers in the right direction.


Solution

  • I just pushed up an example application that does a simple transition when you hit the "/" route using ember.js RC5

    https://github.com/toranb/ember-testing-example

    The simple "hello world" example looks like this

    1.) the template you get redirected to during the transition

    <table>
    {{#each person in controller}}
    <tr>
      <td class="name">{{person.fullName}}</td>
      <td><input type="submit" class="delete" value="delete" {{action deletePerson person}} /></td>
    </tr>
    {{/each}}
    </table>
    

    2.) the ember.js application code

    App = Ember.Application.create();
    
    App.Router.map(function() {
        this.resource("other", { path: "/" });
        this.resource("people", { path: "/people" });
    });
    
    App.OtherRoute = Ember.Route.extend({
        redirect: function() {
            this.transitionTo('people');
        }
    });
    
    App.PeopleRoute = Ember.Route.extend({
        model: function() {
            return App.Person.find();
        }
    });
    
    App.Person = Ember.Object.extend({
        firstName: '',
        lastName: ''
    });
    
    App.Person.reopenClass({
        people: [],
        find: function() {
            var self = this;
            $.getJSON('/api/people', function(response) {
                response.forEach(function(hash) {
                    var person = App.Person.create(hash);
                    Ember.run(self.people, self.people.pushObject, person);
                });
            }, this);
            return this.people;
        }
    });
    

    3.) the integration test looks like this

    module('integration tests', {
        setup: function() {
            App.reset();
            App.Person.people = [];
        },
        teardown: function() {
            $.mockjaxClear();
        }
    });
    
    test('ajax response with 2 people yields table with 2 rows', function() {
        var json = [{firstName: "x", lastName: "y"}, {firstName: "h", lastName: "z"}];
        stubEndpointForHttpRequest('/api/people', json);
        visit("/").then(function() {
            var rows = find("table tr").length;
            equal(rows, 2, rows);
        });
    });
    

    4.) the integration helper I use on most of my ember.js projects

    document.write('<div id="foo"><div id="ember-testing"></div></div>');
    
    Ember.testing = true;
    
    App.rootElement = '#ember-testing';
    App.setupForTesting();
    App.injectTestHelpers();
    
    function exists(selector) {
        return !!find(selector).length;
    }
    
    function stubEndpointForHttpRequest(url, json) {
        $.mockjax({
            url: url,
            dataType: 'json',
            responseText: json
        });
    }
    
    $.mockjaxSettings.logging = false;
    $.mockjaxSettings.responseTime = 0;