trito
trito

Reputation: 11

How do I trigger a function in an Ember component from the test component?

In the unit test ComponentA-test I would like to trigger the function load() in ComponentA, but I have problems doing so.

Before the assert.equal in the below code example I would like to add something simular to this.load() that I would have written in the component to trigger it. But I can't seem to find the right syntax for doing so.

    test('should render some information', async function (assert)) {
       await render(hbs`{{componentA}}`);

       assert.euqal(".info").text().trim(), "info text");
    }

Upvotes: 1

Views: 1195

Answers (2)

Marianna S.
Marianna S.

Reputation: 1095

Update for Octane/Glimmer components: I learned today from this comment by an Ember core team member that they "don't currently support unit testing of Glimmer components"

Copying a suggested workaround in this comment which "let you gain access to the component instance from your rendering tests"

module('my-thing', function(hooks) {
  setupRenderingTest(hooks);

  test('something that wants to exercise an internal method', async function(assert) {
    let component;

    this.owner.register('component:my-thing', class extends MyThing {
       constructor(owner, args) {
         super(owner, args);
         component = this;
       }
    });
    
    await render(hbs`<MyThing />`);

    // now I can interact with `component` without issue
  });
});

Upvotes: 1

stevenelberger
stevenelberger

Reputation: 1368

There's a couple things you can do here but it depends on whether load is an action or not. There may be other ways to test this as well, but these are the most common methods I use.

If load is an action and is triggered by a DOM event (i.e., clicking a button) then you can trigger the function by performing that DOM event in your integration test:

test('should render some information', async function(assert) {
  await render(hbs`{{componentA}}`);

  // if a button has the action modifier:
  // <button {{action "load"}}>Click me</button>
  // then you can do this in your test to trigger the action:

  await click('button');

  // assertions go here
});

If it's simply a regular function in the component and you want to call this function manually on an instance of the component you could try doing so in a component unit test. The only gotcha here is that you won't be able to assert any DOM changes.

test('should do something', function(assert) {

  const component = this.owner.factoryFor('component:componentA').create();

  component.load();

  // assertions go here
});

Upvotes: 2

Related Questions