That’s all we’re going to test. With this list the tests almost write themselves!

Let’s start by generating the scaffold using SimonTest because ain’t nobody got time for that:

Out the bat we get 100% coverage but mind you the goal isn’t to achieve 100% coverage, it’s to properly test the component. In this case we only got tests for the code, not the actual UI the users will interact with.

So let’s test this based on our use cases.

Without a hero

Doesn’t display anything. The key to testing this is to make sure getHero returns undefined and then checking if anything renders.

With a hero

The first thing to do is make sure getHero returns a valid hero for the rest of the tests to use.

Displays some content. Does it display something? Anything?

2. Has a header with the hero name in uppercase. Since we’re getting the native element it’s always a good idea to leverage TypeScript and define the type of the element. In this case it’s HTMLHeadingElement .

3. Has a label with the hero id. Notice how the text “id:” is in a span next to the id number, yet .textContent shows “id: 123”, just like the user would see it.

4. Has an input box with the hero name. Since the input box is bound using [(ngModel)] we have to wait for the component to become stable. IMHO detectChanges should take care of this scenario but that’s a rant for another post.

5. When the “go back” button is clicked it calls location.back(). In the case we’re going to grab the first button on the page but I have to note it’s a bit fragile. In a real component you typically have more elements and classes to make the selector more sturdy. Btw, I see adding IDs for the sake of testing a smell (it’s an easy way to end up with duplicate IDs on a page).

6. Updates the hero property when user types on the input. Changing the value of the input isn’t enough for Angular to pick up the changes, you have to dispatch the input event.