ember.jsember-testing

Ember Integration Test: Component with each helper fails test


While following the emberjs tutorial I couldn't get my component to pass the testing
(https://guides.emberjs.com/release/tutorial/simple-component/).

The tutorial expected the each helper to be placed in the
template file (app/templates/rentals.hbs) to send each element of the array. Instead of placing the each helper in the template file I placed it in the component file
(app/templates/component/rental-listing.hbs) so I wouldn't have to write it out each time I needed to place the rental list.
The error in testing was:
Promise rejected during "should display rental details": Cannot read property 'textContent' of null

This works in testing:

<article class="listing">
  <a
    onclick={{action "toggleImageSize"}}
    class="image {{if this.isWide "wide"}}"
    role="button"
  >
    <img src={{this.rental.image}} alt="">
    <small>View Larger</small>
  </a>
  <div class="details">
    <h3>{{this.rental.title}}</h3>
    <div class="detail owner">
      <span>Owner:</span> {{this.rental.owner}}
    </div>
    <div class="detail type">
      <span>Type:</span> {{this.rental.category}}
    </div>
    <div class="detail location">
      <span>Location:</span> {{this.rental.city}}
    </div>
    <div class="detail bedrooms">
      <span>Number of bedrooms:</span> {{this.rental.bedrooms}}
    </div>
  </div>
</article>

While wrapping the previous code with this doesn't:

{{#each @rentalListings as |rental|}}

{{/each}}

Here's the test:

// @rental is correctly renamed to @rentalListings

module('Integration | Component | rental-listing', function (hooks) {
  setupRenderingTest(hooks);

  hooks.beforeEach(function () {
    this.rental = EmberObject.create({
      image: 'fake.png',
      title: 'test-title',
      owner: 'test-owner',
      type: 'test-type',
      city: 'test-city',
      bedrooms: 3
    });
  });

  test('should display rental details', async function(assert) {
    await render(hbs`<RentalListing @rental={{this.rental}} />`);
    assert.equal(this.element.querySelector('.listing h3').textContent.trim(), 'test-title', 'Title: test-title');
    assert.equal(this.element.querySelector('.listing .owner').textContent.trim(), 'Owner: test-owner', 'Owner: test-owner');
  });

  test('should toggle wide class on click', async function(assert) {
    await render(hbs`<RentalListing @rental={{this.rental}} />`);
    assert.notOk(this.element.querySelector('.image.wide'), 'initially rendered small');
    await click('.image');
    assert.ok(this.element.querySelector('.image.wide'), 'rendered wide after click');
    await click('.image');
    assert.notOk(this.element.querySelector('.image.wide'), 'rendered small after second click');
  });
});

Should I not be placing an each helper in a component or is my testing file not setup correctly?

I can try to create a twiddle if the problem is not clear enough.


Solution

  • Rentallistings you passed in each helper what's the computed value. It should be an array but what's being passed in test rentals is an object. So it will not run over an object hence no output