0

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?

Chris Peters
  • 17,918
  • 6
  • 49
  • 65

1 Answers1

3

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);
});
Chris Peters
  • 17,918
  • 6
  • 49
  • 65
Robert Jackson
  • 534
  • 3
  • 7
  • This worked for me by moving into a separate integration test file as the blog post instructs. Do you feel that unit tests are no longer needed for components, or is it too early to tell? Or I suppose the integration tests are only needed if you're testing UI elements... – Chris Peters Jul 07 '15 at 16:34