Check out a free preview of the full Ember Octane Fundamentals course:
The "Helpers & Unit Testing Setup" Lesson is part of the full, Ember Octane Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

Mike demonstrates how to create helper functions and then navigates to the test runner page for Ember. QUnit, the default testing framework for Ember, is introduced.

Get Unlimited Access Now

Transcript from the "Helpers & Unit Testing Setup" Lesson

[00:00:00]
>> Mike North: The next thing we're gonna do is bring effectively a function into our templates. And the function we're interested in right now is something to handle dates. So I wanna be able to provide this function to date and I want it to be formatted the way I've selected on the right side of the screen.

[00:00:20] In Ember, these are called Helpers. Helpers are these functions that are usable from within our templates. In order to do this, and this is the way I would do it where I'm building a real app. I first wanna get this functionality the ability to format a date in this way.

[00:00:39] I wanna get that into my app in a Vanilla JavaScript way. So we're gonna just create a regular function that does this. And then we're gonna have a thin Ember wrapper around it. Why do I decided to do it this way? Because if I ever need the same utility in my JavaScript files, not just my templates.

[00:01:00] Now, I have a place where I can go and grab that behavior in its simplest, most reusable form. It also makes it really easy to unit test. This is gonna be a pure function where the return value is completely determined by what I give the function as arguments.

[00:01:17] So this is the ideal case for unit testing. So what we're gonna do is we're gonna use Ember CLI's code generation utilities to make a file that Ember calls a a util. And this is just something that'll end up in your utils folder. It's sort of free rein as to what you wanna put there.

[00:01:39] But commonly this is where low level, plain JavaScript code goes. So we're gonna run ember g or generate,
>> Mike North: Util date. So I'm gonna end up with a date.js file in my app/utils folder. And this would be a great place for me to collect any functions that pertain to dates.

[00:02:05]
>> Mike North: Now, since working with this date object and formatting it has nothing to do with Ember, I've given this to you. So let's go back to our starter-files, and you'll see a date.js and a date-test.js. So take the contents of those two files and put them in the two files that Ember CLI created for us.

[00:02:29] You should see those in the output of your Ember G Util date command. So I wanna grab date.js from starter files, copy that. And go to my app/utils folder.
>> Mike North: Paste that in.
>> Mike North: And save. We see no update understandably, cuz this is a function we haven't used yet.

[00:02:56] And then I'm gonna go back to starter files, grab the tests. This is just a set of unit tests where I'm trying various formats of date and making sure they're all coming out in reasonable way. I'm gonna copy that and then look at the Ember CLI output
>> Mike North: There it is, so it's tests, unit tests, utils, and then date test.

[00:03:22] Someone replace the contents of this file with my date tests. Now, Ember CLI has a test runner built in, testing is included. By default you get two unit, but you can swap that out if you prefer Mocha and swap that out with about a minute of work. You just remove the Ember QUnit package and install Ember Mocha instead.

[00:03:50]
>> Mike North: I kind of liked QUnit, the biggest reason for that is Mocha's assertions are driven by throwing errors. What this means is if you have six or seven assertions in a test, and the first one fails, that'll terminate your test early, and you don't get to see whether the rest of your assertions in that test passed or failed.

[00:04:14] So it often means that you have to make several passes. If many things are failing, you kinda have to chip away and solve the first problem to reveal the second and solve the second to reveal the third. QUnit doesn't behave this way, so you get a complete run of your test suite, if that is possible.

[00:04:31] Obviously there are things you can do that will make it impossible to finish your test suite. But you get more feedback and you can fix things with fewer passes. So to view our tests, we're gonna go to /tests, and we should see the QUnit test runner.
>> Mike North: And there it is.

[00:04:55] So there's a lot of ESLint stuff here. This is linting presented to you in the form of tests. I like to disable lintings, especially when I'm doing something like this and I'm not so concerned about style. You can check this all of those will disappear and we can see that everything looks green.

[00:05:15] If we open up this utility test, these are the things that you pasted in. You can see that some of these have nice labels, so we can get an idea for what we're actually testing here. And then these don't have labels so they're just saying here's a generic thumbs up.

[00:05:31] We're gonna be returning to this /test URL often.
>> Mike North: In order to expose this in our templates to make it so effectively we can use this in our templates, we're going to need this helper that I refer to earlier. And we'll reach again back to Ember CLI in order to generate this helper.

[00:05:54] Ember generate helper format-timestamp
>> Mike North: And we'll see that two things were built for us. Number one is this file in the app/helper's folder. That is the helper and along with it we get an integration test. So you'll see often when you generate things using Ember CLI you'll get the thing you're after and a very basic passing test that is ready for you to expand upon.

[00:06:34] So let's worry about the helper first.
>> Mike North: I'm just gonna Cmd+click on that or you can go and find the file and open it. And I'm gonna go back to the non-testing part of our app, the real app here. And the way I wanna explore how this works is I'm gonna put a debugger in here.

[00:06:59]
>> Mike North: And then I'm gonna go to application.hbs and I'm gonna use this helper, so that we can see how it receives any data that we might pass it.
>> Mike North: So I'll just put it right below the channel header. And here's how it looks, it's a handlebars expression, format-timestamp, and the VS code extension is helping us again, affording those misspellings.

[00:07:27] And we're gonna pass it a date. This is me sort of stating how I want to use this thing, and we'll flesh out how exactly it will end up being used. So let's try 05-01-2019.
>> Mike North: So right now what's happening is we sort of see the same value we gave this helper pass straight through.

[00:07:57] And if we go back to the helper, it kinda makes sense.
>> Mike North: Going back to format time stamp. You can see that we get this argument params and we return params. So I'm gonna pop open my dev tools, and I wanna take a look at what is params?

[00:08:18] So I just refreshed and we stopped at the debugger, and if I hover over params. So this is, as the tool tip indicates, it's an array. And the first element of the array is the string that I passed in. And this is how things work when you pass positional arguments to a helper in the way that we have.

[00:08:37] So if we went to application.hbs and we passed another thing here like foo, and then refresh.
>> Mike North: Now, we can see that our array contains two things. So they're in the same order, left to right.
>> Mike North: We could also pass key value pairs like this, bar = "foo", something like that.

[00:09:01] It's the second argument that a helper receives, or will see those key value pairs showing up, and that is called hash. So if we uncomment that,
>> Mike North: And play through,
>> Mike North: And hover over hash,
>> Mike North: There we go, it's an object, bar = "foo". So you can mix and match these as you see fit.

[00:09:28] In this case, we don't really care about hash. We just care about passing something dateIsh. Let me close some of us to get out of the way. We just wanna pass something dateIsh to this. And,
>> Mike North: Let our utility function handle it. So we don't need this,
>> Mike North: And we don't need our debugger anymore cuz we kinda understand how this works.

[00:09:54] So the argument of importance is the first thing in params.
>> Mike North: And I'm gonna just call it dateIsh. This is using the structuring to grab the zero element out of the array. You could also have done dateIsh = params 0, and then we want to pass it to whatever is in date.js.

[00:10:21] And it looks like the name of this function is dateToString.
>> Mike North: So what you need to do, and this is more VS code magic here. So VS code will automatically import the module for me and it'll wire everything up correctly, because I've exported this properly from the sample code that I gave you the date.js code.

[00:10:50] But if you were to do this manually, you would import dateToString. And now we can pass dateIsh as the argument to that. And we're gonna return,
>> Mike North: And we should be in good shape once we resume.
>> Mike North: And there we go, so it's the same date. It's still May 1st, but it has this format that kinda matches what we're seeing in the HTML that we were given.