johnjo
johnjo

Reputation: 1945

Jasmine tests failing over EmberJS needs API

I'm working on unit testing an EmberJS project with Jasmine but I'm having trouble with Ember's needs API.

When I try to run the jasmine tests, they fail on creating a controller instance, if the controller in question has "needs" as well as an init function that calls

this._super()

I get this console error

"Cannot call method 'has' of null"

that when I tried to debug, brought me all the way into the bowels of Ember but I got nowhere with that.

Anyone have any idea what I'm doing wrong

Application.SearchPendingController = Ember.ObjectController.extend({
    needs: ['searchResults', 'search'],
    shouldDisable: false,
    searchResultsController: null,
    init: function () {
        this._super();

        this.set('searchResultsController', this.controllerFor('searchResults'));

        this.get('controllers.search.content').reload();

        this.get('controllers.searchResults').set('content', this.get('controllers.search.content.results'));

    },
    transitionToResults: function () {
        console.log('yay');
    }.observes('this.searchResultsController.content')
});

The jasmine tests throw an error when I try to create this controller

var searchPendingController = Application.SearchPendingController.create();

Anyone have any ideas about this?

Upvotes: 1

Views: 754

Answers (2)

Kingpin2k
Kingpin2k

Reputation: 47367

Even better is if your controller needs to access the other controller for calculating some property is to have the container create the controllers for you.

Application.SearchPendingController = Ember.ObjectController.extend({
  needs: ['searchResults', 'search'],

Testing

  var searchModel = something, 
    searchResultsModel = something, 
    searchPendingModel = something;

var container = Application.__container__,
  searchController = container.lookup('controller:search'),
  searchResultsController = container.lookup('controller:searchResults'),
  searchPendingController = container.lookup('controller:searchPending'),
  searchController.set('model', searchModel),
  searchResultsController.set('model', searchResultsModel ),
  searchPendingController.set('model', searchPendingModel );

Upvotes: 0

Teddy Zeenny
Teddy Zeenny

Reputation: 3971

When you create a controller, Ember.js checks the dependencies (needs) in the init method. Checking for dependencies assumes you have an Ember.js application, and this application's container is found in the container property of the controller. This all works great if Ember.js created the controller for you.

Your error is happening here, in the verifyDependencies function.

If you don't want Ember.js to create the controller for you and want to create it manually, (which is what you are doing here), you will need to manually set the controller's container property to the application's container.

Application.SearchPendingController.reopen({
  container: Application.__container__
});

Unit testing controllers is tricky and requires that you dive into the internals of Ember.js. My advice, let Ember.js create the controllers for you, and use integration tests instead of unit testing them.

Upvotes: 8

Related Questions