How to test an Ember model's computed property that has relations dependencies?

与世无争的帅哥 提交于 2019-12-24 10:40:04

问题


I'm writing Qunit tests to test An Ember model, but having a hard time testing computed properties that have a relation dependency (the computed property triggers another model's computed property).

The model that am testing (CoffeeScript):

Customer = DS.Model.extend
  firstName:      DS.attr('string')
  lastName:       DS.attr('string')
  phones:         DS.attr('embedded-list')
phone: (->
    @get('phones.firstObject.number')
  ).property('phones.firstObject.number')

fullName: (->
    [@get('lastName'), @get('firstName')].join(' ') )
  ).property('firstName','lastName')

The meeting Model:

Meeting = DS.Model.extend
  customers: DS.hasMany('customer')

  startAt:   DS.attr('isodate')
  status:    DS.attr()
  objective: DS.attr()

 customerPhones: (->
    phones = []
    @get('customers').forEach (c) ->
      c.get('phones').forEach (ph) ->
        phones.push(ph.number)
    phones
  ).property('customers.@each.phones')


  firstCustomer: (->
    @get('customers.firstObject')
  ).property('customers.firstObject')

 firstCustomerFullName: (->
    @get('firstCustomer.fullName')
  ).property('firstCustomer.fullName')

Now, testing customerPhones, and firstCustomerFullName is giving me a real hard time...

My test looks as follows:

`import { test, moduleForModel } from 'ember-qunit';`

moduleForModel('meeting', 'App.Meeting',{
   needs: ['model:customer']
   setup: ->
     Ember.run do (t = @)->
       ->
        customer = t.store().createRecord 'customer', firstName: 'John', lastName: 'Smith', phones:[]
        customer.get('phones').addObject(Ember.Object.create({tag: 'home', number: '111222333'}))
        customer.get('phones').addObject(Ember.Object.create({tag: 'work', number: '444555666'}))

        t.subject().set('customers.content', Ember.ArrayProxy.create({content: []}));
        t.subject().get('customers.content').pushObject(customer)    
 teardown: ->
  },(container, context) ->
      container.register 'store:main', DS.Store
      container.register 'adapter:application', DS.FixtureAdapter
      context.__setup_properties__.store = -> container.lookup('store:main')
)

test "it's a DS.Model", -> ok(@subject())

test "attributes: can be created with valid values", ->
  meeting = @subject({objective: 'Follow up'})
  Ember.run ->
    equal(meeting.get('objective', 'Follow up'))


test "properties: firstCustomer & firstCustomerFullName & firstCustomerPhone", ->
  meeting = @subject()
  Ember.run ->
    equal(meeting.get('firstCustomer.fullName'),  'Smith John')
    equal(meeting.get('firstCustomer.phone'),     '111222333')

Now, I used some techniques in this test, that I found in an answer here on Stack Overflow, but I can't seem to find it now.

That worked perfectly few days ago, now (it seems nonsense I know) whenever I run the test, it errors:

Assertion Failed: You cannot add 'meeting' records to this relationship (only 'meeting' allowed)

I don't know where the error is, nor how to fix it. Spent all the day monkeying around, No outcome.

How can I resolve this?


回答1:


Okay, what I have so far is too much for a comment, so I'm going to do a WIP Answer.

  • I removed most of the run loops, they are only necessary for async processes.

  • I changed some of your computed properties to computed.alias properties

i.e.

phone: (->
  @get('phones.firstObject.number')
).property('phones.firstObject.number')

to

phone: Ember.computed.alias('phones.firstObject.number')
  • I ripped out most of the setup, Ember Data eagerly loads the store on its own and will use fixture ids etc without specifying it. (this part can be put back it, it just isn't necessary in this context).

i.e.

  },(container, context) ->
  container.register 'store:main', DS.Store
  container.register 'adapter:application', DS.FixtureAdapter
  context.__setup_properties__.store = -> container.lookup('store:main')
  • And I apologize in advance, I'm not a fan of coffeescript, so I put it all in js. Now the question is, if you're still seeing any issues we may need to find out what versions of Ember, ED, and Ember Qunit you are using.

http://emberjs.jsbin.com/OxIDiVU/625/edit




回答2:


I found this question looking for 'how to unit test a computed property that uses a hasMany'.

Here is a simple example of how I did it (thanks to Kitler):

Fridge Model:

foods: DS.hasMany('food', {async: true}),

inDateFoods: Ember.computed('foods.@each.{ignoreEndDate,endDate}', function() {
  let foods = this.get('foods');
  let now = moment();
  return foods.filter(f => f.get(ignoreEndDate) || moment(c.get('endDate')).isAfter(now));
})

So say we now want to test inDateFoods in a unit test? Then do this in your fridge model test file:

import Ember from 'ember';
import { moduleForModel, test } from 'ember-qunit';
import Fridge from '../../../models/fridge';

Fridge.reopen({
  foods: Ember.computed(() => [])
});

moduleForModel('fridge', 'Unit | Model | fridge', {
  // Specify the other units that are required for this test.
  needs: ['model:food']
});

test('filters correctly', function(assert) {
  assert.expect(1);
  let model = this.subject();
  model.pushObject(Ember.Object.create({foods: [{id: 1, ignoreEndDate: false, endDate: '2050-03-08T00:00:00'});

  assert.equal(model.get('inDateFoods.length'), 1);
});

They key here is to reopen your model to remove the has many, and push the object after doing this.subject. Before doing the reopen we were getting the error All elements of a hasMany relationship must be instances of DS.Model, you passed [[object Object]] error.



来源:https://stackoverflow.com/questions/24123948/how-to-test-an-ember-models-computed-property-that-has-relations-dependencies

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!