Chris Peters
Chris Peters

Reputation: 18090

Testing an Ember.js component using hasBlock

I have this component set up (stripped down to its minimum):

<a href={{href}}>{{text}}</a>

{{#if template}}
  <button {{action "toggleSubmenu"}} class="global-nav-toggle-submenu">
    <i class="caret-down"></i>
  </button>
{{/if}}

And this test:

test('has a toggle button if a submenu is present', function(assert) {
  var component = this.subject({
    template: Ember.HTMLBars.compile('<ul class="global-nav-submenu"></ul>')
  });

  assert.ok(this.$().find('.global-nav-toggle-submenu').length);
});

This runs fine, but I get a deprecation notice from Ember:

Accessing 'template' in <app-name@component:global-nav-item::ember540> is deprecated. To determine if a block was specified to <app-name@component:global-nav-item::ember540> please use '{{#if hasBlock}}' in the components layout.

When I change the template to use hasBlock instead:

<a href={{href}}>{{text}}</a>

{{#if hasBlock}}
  <button {{action "toggleSubmenu"}} class="global-nav-toggle-submenu">
    <i class="caret-down"></i>
  </button>
{{/if}}

The test fails. Logging this.$() to the console shows that the hbs template file seems to be ignoring the template I'm adding programmatically.

In the test, I've tried swapping out template with block, layout, hasBlock, content, etc., with no success. I've tried initializing the subject with hasBlock: true as well.

And the logic runs fine when loading a page in the regular development app that has a block applied:

{{#global-nav-item text="Hello" href="#"}}
  Some Content
{{/global-nav-item}}

Is there some other way that I should be setting up my components in unit tests in order to test this logic?

Upvotes: 0

Views: 549

Answers (1)

Robert Jackson
Robert Jackson

Reputation: 534

In general you should use the "new" style component integration tests for this type of thing.

See the following resources:


Update: Based on the blog post linked from Robert's answer, here is the new test code in tests/integration/components/global-nav-item-test.js:

import hbs from 'htmlbars-inline-precompile';
import { moduleForComponent, test } from 'ember-qunit';

moduleForComponent('global-nav-item', 'Integration | Component | global-nav-item', {
  integration: true
});

test('has a toggle button if a submenu is present', function(assert) {
  this.render(hbs`
    {{#global-nav-item text="Hello" href="/"}}
      <ul class="le-global-nav-submenu"></ul>
    {{/global-nav-item}}
  `);

  assert.ok(this.$('.global-nav-toggle-submenu').length);
});

Upvotes: 3

Related Questions