6

I have several class-based helpers in my app, mostly so I can include the i18n service. Everything works nicely, however, I can't figure out a way to test them.

The auto generated test is not working, as it expects a function to be exported and complains, that undefined is not a constructor:

module('Unit | Helper | format number');

// Replace this with your real tests.
test('it works', function(assert) {
  let result = formatNumber([42]);
  assert.ok(result);
});

So I tried using moduleFor as it already worked for testing mixins, but also failed:

moduleFor('helper:format-number', 'Unit | Helper | format number', {
  needs: ['service:i18n']
});

test('it works', function(assert) {
  let result = FormatNumber.compute(42);
  assert.ok(result);
});

I tried all the different versions of instantiating the helper object and calling compute on it but nothing worked. In the end it either always returned null or failed with an undefined error.

Did anyone manage to succeed where I failed?

irruputuncu
  • 1,460
  • 1
  • 11
  • 24

1 Answers1

4

The issue in your example is that you're trying to call compute as a static method on the class itself, when what you really need is an instance of the class.

Here's an example for a Class-based helper that I'm testing. Note; it uses mocha, not qunit, but all of the concepts are the same.

import { expect } from 'chai';
import { beforeEach, describe, it } from 'mocha';
import ShareImage from 'my-app/helpers/share-image';

describe('ShareImageHelper', function() {
  beforeEach(function() {
    this.helperClass = ShareImage.create({
      location: {
        hostWithProtocolAndPort: ''
      }
    });
    this.helper = this.helperClass.compute.bind(this.helperClass);
  });

  it('calculates the `assetPath` correctly', function() {
    const assetPath = this.helperClass.get('assetPath');

    expect(assetPath).to.equal('/assets/images/social/');
  });

  it('calculates the path to an image correctly', function() {
    const value = this.helper(['foo', 'bar', 'baz']);

    expect(value).to.equal('/assets/images/social/foo/bar/baz.png');
  });
});

The key here is that on each test run (in the beforeEach callback) I create a new instance of the helper, and then create a function that my tests can call the same way the template helper will be called (this.helper). This allows the tests to look as much like the real code as possible, while still giving me the ability to modify the helper class during tests, which you can also see in the beforeEach callback.

Alex LaFroscia
  • 961
  • 1
  • 8
  • 24
  • As of `ember-cli-mocha@0.12` you can do integration or unit tests as shown here: https://github.com/emberjs/ember.js/blob/master/blueprints/helper-test/mocha-0.12-files/tests/__testType__/helpers/__name__-test.js – acorncom Mar 14 '17 at 21:38