Check out a free preview of the full Production-Grade Angular course:
The "Widget Facade Testing" Lesson is part of the full, Production-Grade Angular course featured in this preview video. Here's what you'd learn in this lesson:

Lukas demonstrates how to override a provider by walking students through an example of a test involving the widget facade.

Get Unlimited Access Now

Transcript from the "Widget Facade Testing" Lesson

[00:00:00]
>> One thing that I wanna call out here is you'll notice that I am declaring the reference or I'm declaring a property on this, that is of type widgetsfacade. And if we go down here in the providers, and so this is one of the reasons why I love dependency injection so much, is I'm saying, hey, provide widgetsfacade.

[00:00:35] Instead, use this value over here. And so it's very easy when you're testing to override a provider and give it something else in exchange. And so rarely do I ever use real services or real dependencies. And so, now I can come back here and I can say TestBed.inject, which then returns whatever you give it, widgetsfacade.

[00:01:07] Which now the question is, is it returning the actual widgetsfacade, or my mockwidgetsFacade? Well, it's the mock. And so now I can start to do things in control how it behaves. And so what does this look like? What I've done here is that I've created a new lib, and it's just called testing.

[00:01:32] And maybe I could call it something else but I found that I was creating the same mocks across a bunch of different tests. And so if I click on this, and it's going to take me there. It's doing this weird thing. So what I'll do, we'll go to widgetsmock and you'll see here testing lib mocks widgets.

[00:02:00] That in here I have a mockwidget so I can just use this over and over. I have an Emptywidget and I have a mock service and a mock facade And all I'm doing is I'm using this observable operator of which whatever you put into it, it just returns that as an observable.

[00:02:31] And so I don't need to actually do anything in this case, but I'm overriding the injector and I'm saying don't use the real one, use this mock one. And because when I call this selectwidget the spy is catching it and it's not doing anything. But even if it did it's just an empty method.

[00:03:00] It's just to satisfy the interface of that and so what you can do is I believe and. I think it's like this or might be a single. Depends on what assertion library but basically what you gonna do is you can say I want to spy on this but I also want to allow it to pass through.

[00:03:26] And so in some cases, you actually want to say I want to spy, but I needed to actually go through and continue into the rest of the application. So before I go any further, We've talked about the basic component structure for testing. And then I've talked about spies and mocks, and really we're using those in conjunction.

[00:03:53] Does anybody have any questions about what I've just covered so far?
>> So the question I have is on your presentational components, we could actually do these tests as well where we're looking at the DOM right at the template? And you were saying use those sparingly, but there will be times probably where we need to do those tests?

[00:04:25]
>> On a presentation component that you can use the debug element to manipulate the DOM and we should use it sparingly.
>> Is there an overhead by using those? Because if I want to make sure that something in the DOM in the templates looking the way should is there an overhead?

[00:04:50]
>> No, and you can. What I would also recommend is that this is what end to end testing is for. And so I would use unit testing to test units of logic. So the question is, is there overhead for using a debug element to write assertions against the DOM?

[00:05:12] There's not, and there are times where I will use it. But, it should not replace, and integrated end-to-end testing strategy. And so to that end is unit tests are for units and or units of code, end to end testing is for testing really how things work end to end or in relation to itself.

[00:05:43] And so with Cypress this is where this comes in. Is I would test that it's actually rendering in Cypress, which is not super hard to do versus trying to write unit style tests on the DOM. My final point would be this. That a lot of times the things that are causing us the most problems they're not big huge issues in and of themselves.

[00:06:22] That if you've ever had to walk a long distance with a pebble in your shoe. All of a sudden that pebble becomes very, very, very painful. And so I think it's interesting in terms of the tension of the narrative arc of this workshop is that, we're talking about large scale production applications.

[00:06:46] And what I'm having to constantly pull everybody back to is stop writing functions that do more than one thing. Stop nesting your logic structures. Stop breaking the single responsibility principle. If you just did that, I would say 80% your problems would go away, and you would be able to write a lot of testable code.

[00:07:08] And so reduce complexity, reduce coupling, increase the right kind of cohesion. And when you manage your complexity in a way that is just one layer above all interested parties, I'm going to use that for the rest of my life. So thank you Bernardo for being the catalyst to that.

[00:07:33] We can start to organize our applications and our work into really interesting things, which is why we were able in a single day with commentary is to really create this workspace that has two applications. That's pulling from an API that has test with state management. And there are things that I encourage you to dig in and look into and see how things kind of fit together.

[00:08:03] But the answer is not to increase in terms of complexity but really to increase your understanding, which a lot of times will feel like in a way, you're going back to square one. And everything becomes very simple. And that's ultimately where I want developers that I work with, and that I train, and that I spend time with is.

[00:08:31] Let's go back to a place where coding is so simple and simplistic is that we can approach it with a beginner's mind, and it makes sense. And from there we start to extend it into doing really interesting complicated, ultimately scalable things that we put into production