Traditionally you had to create DOM elements to test a directive but by shifting our focus to components, writing unit tests got a lot easier using $componentController within ngMocks. We can now test our component's controller with an easy to use API that does not require us to spin up any DOM elements to do so. In this lesson, we will see how our ES6 tests are transpiled, learn how to test a component using $componentController and talk about how to simulate lifecycle hooks.
[00:00] In this lesson, we are going to learn how to test a component using the component controller Mock, that ships with ngMocks.
[00:09] First, let's take a quick moment and talk about how testing works with Webpack in ES6. Because we have to transpile our test just like our application, we need to tell Webpack how to do that, so we've created this spec bundle to convey to Webpack that these are the modules that we want to import and this is how to do it.
[00:27] We're importing Angular from angular-mocks, and then we're defining a context for our test, and then we're using that to bundle those up. If we go into the Karma configuration file, you can see that we have Karma Webpack, and we're passing in our bundle to be, basically, pre-processed before it goes to Karma.
[00:54] Then from here, let's look at our category spec. We have a categories module controller, a component template with some very simple tests. We're just testing the name of the module that our category contains a category item, and that our component has template controller as controller equals the category's controller. There's not a lot to test here, but we are going to take this a step further and show how to test the actual component controller.
[01:22] Let's initialize some variables here -- component, component controller, and categories model. Then from here, let's go ahead and do some additional initialization. Because we're testing a component, we need to import the categories module, and then we are going to mock out the categories model.
[01:43] We're going to do $provide.value categories model, and then we're going to simulate or rather mock out the getCategories method, and simulate a fake promise. It's just an object with a then method on that.
[01:59] Then from here, just in another, before each block, I like to break these out. We are going to assign or rather inject the component controller in the categories model using this underscore wrapper here, and then assign those to our local variables.
[02:21] So categories model equals the _categories model, and component controller equals _component controller. Then from here, let's describe our test block for the controller. Our test is that when the component is created, that the component controller calls categories model.getCategories immediately.
[02:50] This is going to be a bit of a funny test, as you'll see in just a moment. The first thing we need to do is create a spy on getCategories on categories model, and we're going to call through. From here, let's initialize our component using component controller. So it will take our component name, which is categories, and then its dependencies, in this case, it's just categories model.
[03:12] Then from here, let's write our assertion, so we expect categories model getCategories to have been called. Let's hop into the command line. We will run our test, and let's see what happens.
[03:30] Oh no. The caveat here is that because we're not actually adding it to the DOM, some of the lifecycle hooks will not fire. So a little bit of hand-waving and we manually have to call this. Component OnInit() and let's run this one more time. It should be green, yes, all the way down.
[03:49] This is how you test a component using the component controller.