This course has been updated! We now recommend you take the Angular 13 Fundamentals course.
Transcript from the "Unit Testing in Angular" Lesson
>> Let's cover Angular component testing fundamentals. And it is interesting to me that when I start talking about component of an architecture, I get really excited because I think it's just incredibly important how you architect your application and just the implications that it has a very high level isreally compelling to me.
[00:00:26] And I think you cannot overstate the importance of having good component architecture in your application. Now, the funny thing is, when I start talking about Angular testing that. I do not get as excited. I think most people when they think of testing, they just kind of freeze up.
[00:00:50] And at the same time, I have kind of almost the opposite reaction of talking about testing versus component driven architecture, but it is equally as important. And when you look at an application, and you say, well, how does this work? An answer of well, it hasn't broke is not really acceptable because there will be a time it too in the morning, or, a hacker comes in and something bad happens and then it becomes a huge problem.
[00:01:32] And so, when you're building applications, the question is really how do you know anything and the answer is with feedback loops. That when you're building an application, like a proof of concept that it's important to test your application. But I would not say do unit testing at the onset because you don't want you're building.
[00:01:58] You're doing user testing. It's very high touch, it's very analogue. But then once you've validated what you're building, then you start to build out your unit tests and that becomes very, very important. And then once everything starts to come together, then you start to add in end to end testing.
[00:02:16] So you start to test these units or these features in conjunction. And so it's really, really important to make testing a first class citizen and a part of your development process. And I would be willing to bet a lot of money that as you're watching this, if I asked you, what is your test coverage of the application you are working on right now?
[00:02:48] And I imagine that some people are saying, well, it's 80%. And to that, I applaud you, that's amazing. Most of the time, I kinda get this embarrassed like that, we're working on it. And part of that is because one, I think teams haven't doubled down. It really made it just a mandatory part of their development process.
[00:03:13] But secondly, and this is what I really want to touch on, is, when you talk about testing, you have to talk about the code you're testing. And the reason why most people do not test is because it's really hard. The reason why it's really hard is because, well, one, life is hard, complicated, programming is hard and complicated.
[00:03:37] But, because there's this diversion off of kinda these fundamental programmatic principles I see a lot of code that the reason why they don't have unit test is because it's impossible to test. And so one of my favourite saying is there's not enough time in the world to write good tests for bad code.
[00:04:01] And so I just really encourage you as we go into this module, think about testing not just on from a testing perspective is this isolated activity. But really think about it in the context of the code that you write. And if you write clean, good code, if you write fine grain code that does one very specific thing and it's well defined it's a lot easier, to write test.
[00:04:29] And so that's just a bit of a precursor, that when you think about testing, also, be diligent about the code that you're writing. Because, what will happen is you'll create technical debt in your code. And then it's very, very hard, to test in most teams just to like, I give up, and then you get this technical debt.
[00:04:47] And then how they solve that is they feel like, well, if I just switch to this new fancy framework, everything is going to be solved. And I've seen time and time again, you have a team on Angular, and they're just like, well, if I burn it down and do it and react, things will be fine.
[00:05:01] And then it doesn't go well. So then they burn it down and go to View and back. Is that testing should be a first class citizen. But clean code is the Emperor. It is the king write clean code, and it's much easier to write test. All right, so with that said, let's talk about testing as it pertains to Angular.
[00:05:30] So we hop into this code, one thing that we can just point out right away. And so I'm going to close down these files here is whenever you generate a component. So let's look at this users component we just generated. That it generated not only the component, but it generated the spec for the component.
[00:06:04] And so you get this working test right out of the gates. And so they've done a really nice job of making it easy to write tests by saying, here's a working test for this component. Now what we need to do is what I would like to do is step through the spec and talk about the pieces here and what is happening and what each part in the spec that they've generated does.
[00:06:42] So I think it'd be very easy to just say, I've got this test, we're good. But it's really important to dig down and check out and understand, like, what are these pieces doing? And so, the first thing that I want to point out is, and I'm just gonna kind of comment this out real quick.
[00:07:05] Or pieces of this. And we're going to go through this kind of step by step, and I'm going to unpack what's happening in this component. So the first piece of this is the test bed. And so, the test bed, let me comment this as well. The test bed right here is, this is essentially the the context or the the mechanism responsible for creating the environment for your test to run.
[00:07:49] So this is like the single most important piece when you're testing angular components. And It's responsible for essentially booting up or configuring or essentially setting up a very controlled Angular environment for you to run your test in. And so if we look here, I'm gonna come out of this line as well, so we can just focus on this, TestBed.configureTestingModule.
[00:08:24] And so what this does is this gives you an opportunity to create a very specific module for you to run or test your component in. And so, you want to run this in a before each block before all of your tests. So before you run your test what you're doing is you're saying testbed configure testing module.
[00:08:54] And you're setting up essentially an Angular module for your component, or your service or whatever it is to live in, so that you can test it. And so we're saying Testbed.configureTestingModule. And I want to declare this user component. Well, that's pretty interesting, because if we go over to our app module, let's look at that.
[00:09:22] Entry module declarations,users component, so here it is. Same thing is we're declaring that we want to test this component. Now, the next piece to this is, now that we've configured the module is that we need to create a fixture. And so a fixture essentially creates an instance of the component to test and then it returns this in a test fixture that you can then start to do some interesting things in and access that component that you've created.
[00:10:07] Because you have the testing module or the testbed which creates the module, and then within that, then you can create a fixture that has an instance of that component that you can start to manipulate and access. So, We have fixture, component fixture up at the top here. And let's start to unpack this a bit more.
[00:10:33] So we're saying, configure the testing module, then compile the components. But if we go down into the second before each block, and I'll explain why there's two. Is we're calling fixture Testbed. Create usersComponent. So what it's doing is it's returning a testbed with an instance of that component within the testbed that you can access.
[00:11:03] So we're saying fissure is a component fissure with a user component in it. And so now We're saying testbed create component and return me the users component. And then what we can do is we can access the component by calling fixture.componentInstance. And what this does now is we now have an instance of this component that we can start to access, and we can manipulate, and we can call methods on, and we can test, and we start to do this.
[00:11:43] So now, this testing piece has done a really good job of saying I'm allowing you to create a very specific module to run this in. And I'm going to allow you to create this component in isolation so that you can start to work with. And so, with the testbed that We have created a module, we've created a fixture using Testbed.createComponent.
[00:12:17] And then by calling fixture.componentInstance, we now have an instance of that component. So now, for instance, if I go here, and I created a title property I could say Hello Users. Now within the Spec here, I can say it should have a title or should have the correct title.
[00:12:59] Then we'll create a federal function. We'll go here. Close this out. And now what we can do is we can say expect component.title. And so you saw it already picked that up. To be, Hello. Users. There we go. And so let's go ahead and Let's just go ahead and run these tests.
[00:13:42] And let's see what happens. So I'm going to go here. And from the command line, you just do NPM run test. And this is going to spin up the karma test runner. So you get this for free. And it's just going to run so you can see it's launching a browser.
[00:14:06] And, This should work but possibly not. So, as we've been coding. We have run into a bunch of stuff, but here we go. Let's focus on this one right here. So, obviously got a couple failing test, but more importantly this one right here. Expected Hello Users to be fail.
[00:14:34] So let's fix this one. So we'll go back into our code and We'll change this to Hello Users. Let's go back here. And, now that should be gone perfect. And so we'll actually fix these in just moment while they're here, so this is also kind of going to get into something that's what we'll talk about in a moment.
[00:15:11] But let's keep going just a little bit further down this. And we're gonna focus on this component, and then we'll kind of go in and I can show you how to fix kind of the rest of those tests because you will run into this quite a bit. So when you're running a test, configure the module, create the fixture and then get the component instance.
[00:15:35] Now, this is done for you kinda get this for free. So it's really easy to kind of just not think about the what's actually happening but that is the sequence of the events.