1

I'm working on an Ember component with an init function that I'd like to add a unit test for. The component has the following properties:

1) The init function must not be run more than once, and

2) The component depends on having a model (currentUser) passed to it.

So far I have tried writing a test like this:

test('#init', function(assert) {
  const component = this.owner.lookup('component:component-that-depends-on-property');

  const currentUser = make('user');
  component.set('currentUser', user);

  component.init();

  assert.ok(component.somethingHasHappened);
});

My problem is that init method is run on the owner.lookup line, meaning I have no way of getting the currentUser into the component before it runs. Again, I cannot run the init method more than once without blowing up the component's state.

I noticed that the lookup method takes an options argument and thought I might be able to use that to pass currentUser in, but that doesn't seem to work and I couldn't find much documentation on the lookup method.

I'd like to avoid writing an integration test for this, if possible. Is there a good way of doing this/workaround I'm not seeing?

Glyoko
  • 2,071
  • 1
  • 14
  • 28
  • I would recommend to test components with integration tests that render the component. Otherwise you are not testing the public API of that component but implementation details. You are facing one of this issues cause by that. – jelhan Oct 02 '19 at 07:56
  • Can you explain why `The init function must not be run more than once`? – bartocc Oct 03 '19 at 07:15
  • It's just the way it's built. It's old and massive code and is too complicated to refactor now. Planning on fixing it, but I'd like to have tests around it before working on it. I would very much like it to be idempotent though. Kind of the motivation for this to begin with. – Glyoko Oct 03 '19 at 18:09

2 Answers2

2

I would suggest writing integration tests for components. Avoid writing unit test cases for components rather write unit test cases for controllers, mixins, models, routes, services

prat_bhan
  • 129
  • 4
  • 1
    Can you link to something explaining why? An article? I haven't seen anything recommending against unit testing components. – Glyoko Oct 02 '19 at 16:58
  • When you generate a new component, it creates an integration test along with it, as this is the recommended way to test them. See "Testing Components" in the EmberJS guides here: https://guides.emberjs.com/release/testing/testing-components/ – QMFNP Oct 07 '19 at 18:42
  • The consensus does seem to be that integration tests are recommended so I think I'll go this route. But I still don't understand why. I see that integration tests are autogenerated, but that doesn't explain why they're preferred. I would have expected unit tests to be preferred, since they are by their nature lighter and more self contained than integration tests. – Glyoko Oct 18 '19 at 02:52
1

If you do unit test the component, you can do:

const component = this.owner.factoryFor('component:component-that-depends-on-property').create({
  currentUser: user,
});

That will create an instance of your component with currentUser set. You will not need to call init() explicitly because it is called on create().

Patrick Berkeley
  • 2,206
  • 21
  • 26