I’m trying to do a Jasmine test of ember-data (using the current master) using the DS.FixtureAdapter. I’ve tried dozens of variations on the below code (with and without trying to create an Application namespace). I’ve also gone into the ember-data source to try and see what’s going on, as well as referenced the tests in ember-data itself as an example.
I’ve also tried variations of Person.find(1), using Ember.run blocks and Jasmine wait()’s.
Whatever I try, store.find(Person, 'test') returns a result but attempting to get one of the attributes results in null (test assertion fails). What is it I’m not seeing? Thanks for any help!
describe "a test", ->
store = null
Person = null
beforeEach ->
store = DS.Store.create
revision: 11
adapter: 'DS.FixtureAdapter'
Person = DS.Model.extend
firstName: DS.attr('string')
lastName: DS.attr('string')
age: DS.attr('number')
it "works or does it", ->
Person.FIXTURES = [{
id: 'test'
firstName: 'Kyle'
lastName: 'Stevens'
age: 30
}]
kyle = store.find(Person, 'test')
expect(Em.get(kyle, 'firstName')).toEqual('Kyle')
This is a timing issue. When you call
store.find()it runs query asynchronously and returns a model promise. That means the query is still running (or scheduled to run) when control returns to your test, resulting in a failed expectation.This is what we love about ember, it means your app can treat kyle as if the data were present and trust that values will be updated automagically via bindings when the data becomes available.
Of course all this magic is not so great when it is preventing your test from passing. Here are some alternative approaches:
1) Register a
didLoadcallback2) Instead of
didLoadcould use more blackbox testing approach and just verify that the name is set propertly within 100 ms of having called find – of course this can lead to brittle testsEmber.run.later(this, function() {
console.log(‘should = kyle: ‘, Em.get(kyle, ‘firstName’));
console.log(‘should = kim: ‘, Em.get(App.kim, ‘firstName’));
}, 100);
I believe that in a jasmine test you could wrap your setup code in a runs() method and use
waitsForto verify that the value has been set as expected:See this JSBIN for working (non-jasmine) example:
http://jsbin.com/apurac/4/edit
See this post for tips on async testing with jasmine: http://blog.caplin.com/2012/01/17/testing-asynchronous-javascript-with-jasmine/
Also, be sure to set
Ember.testing = truefor all of your tests. See this SO post for detail: Is it recommended to set Ember.testing = true for unit tests?