Basics of Unit Testing in Angular

Buğra Mert Ayar
Logiwa Tech
Published in
6 min readFeb 15, 2022

--

In this article, I will give some information about Unit Tests in Angular applications. Before we start, we must talk about a very important method which is TDD (Test Driven Development).

Test Driven Development (TDD)

TDD is a development method developed by Kent Beck. Test-driven development (TDD) is a software development process relying on software requirements being converted to test cases before the software is fully developed, and tracking all software development by repeatedly testing the software against all test cases. This is as opposed to software being developed first and test cases created later.

If you have a general understanding of TDD, now let’s get back to the topic which is Unit Testing in Angular applications.

What is Unit Test

Unit test is a test of a single unit of code. Of course, the definition of a unit is purposely big. A unit could be whatever you define it to be, but generally, it should be small as possible. Most developers consider a unit to be a single class, although a few related classes can often be considered a unit.

Why is Unit Test Important

Before any code is deployed, it is subjected to unit testing to ensure that it fulfills quality standards. This promotes a dependable engineering environment that prioritizes quality. Unit testing saves time and money during the product development life cycle, and it helps developers design better, more efficient code.

There are two types of tests we often talk about, unit tests and end-to-end tests. It’s useful to see the difference between the two.

Unit Tests:

· They are fast. Unit tests should run in milliseconds.

· Involves isolated pieces of code, so only a very small portion of your entire system should be active during any single unit test.

End-to-End Tests:

· End-to-end tests will tend to be slow, usually several orders of magnitude slower than a unit test.

· They will exercise the entire system, so you will need to have your complete system up and running in order to run your end-to-end tests.

Due to the speed factor, we generally write many unit tests and few end-to-end tests. But in this article, we are not going to go through how to write end-to-end tests.

A good unit test should be

· Fast. If it takes a long time to complete a unit test, you won’t run it very often, and it will lose its value.

· Cheap to write

· Unit test should cover a single state change, meaning you have put your system in a given state, you make a change to that state and then you test that result was exactly what you expected.

· A unit test should assert one thing. That doesn’t mean that you only have one line of code for your assertions but you are just checking that one specific thing happened.

· Doesn’t cross process boundaries so it shouldn’t call out to a database or out to an HTTP server or anything like that.

· Reliable. A unit test should never fail due to external conditions such as timing with other tests, race conditions or anything like that. It should always pass or fail based on if the code itself is correct or incorrect.

Unit Test Structure

There are two terms that we should know about the unit test.

AAA (Arrange, Act, Assert)

The AAA (Arrange-Act-Assert) pattern has practically become the industry standard. It advises that your test method be divided into three parts: arrange, act, and assert. Each of them is only in charge of the section for which they were named.

AAA (Arrange, Act, Assert)

· The arrange part is where you create the initial state of the unit test. This could be as simple as constructing a class or as complex as creating starting data and setting 10 different state flags.

· The act part is where you change something. Maybe you call a method on your class or change a variable. In any case, you act on the system and cause the state to change.

· The assert part is where you check that the expected result happens given the initial state and the change in state.

Damp

Although some people have created an acronym out of this word, it is more useful to simply consider the meaning of the word damp. You may have heard of the term dry in programming. Dry is an acronym that stands for don’t repeat yourself. This is the principle that you should never duplicate code. Any code duplication is a problem and should be fixed.

Although that is true for the code we write, when it comes to testing, we do not have to be quite so draconian. In fact, we say that our tests do not have to be dry. They can be a little damp. Not yet, we do not want lots of duplication but a little bit is okay.

The reason for this is that a good test should tell a story.

Mocking

Mocking is the mechanism of replacing a dependency with a fake piece of code that does less than the original code did in a meaningful way. We do this for a few reasons, speed, ease of testing or to just avoid code that we don’t want to test.

Let’s assume that we have a test for an order object. This is the code that we are testing. Furthermore, that order object uses an HTTP object to save changes to the server. Of course in a unit test, we don’t actually want to make any HTTP calls so we need a mock HTTP object such that when the order object calls the post method on the HTTP client, it simply returns immediately. The test can still be run but we wont be using the real HTTP object. In this case, we want to mock the HTTP object. So we replace the HTTP object with a MockHttp object that has dummy methods just for our test only.

Angular Basic Testing Tools

As the angular team recommends we are going to use angular-cli to create our app. By doing this the configuration of jasmine and karma comes resolved for us.

Jasmine

Jasmine is the unit testing framework that usually use with Angular. There are several testing frameworks out there but Jasmine is one of the most popular one.

It uses four main functions:

describe() => Which is the containing function for a süite of tests

beforeEach() => Which gives us a place for common setup code.

it() => Each one creates a seperate unit test.

expect() => Which is how we assert that the test passed. In our expect functions, we use what’s called matchers. Matchers are what allow us to express what we are expecting. For example, we may expect that a certain value is 5. In that case we can use the toBe matcher where we specify that we expect the value to be 5. Jasmine includes a lot more matters such as toContain and toBeDefined matchers. https://jasmine.github.io/api/2.7/matchers.html

Now, this whole test is a little bit of a silly example since all we do is create a property on an object, initialize it to one value, set it to another value and then assert that it is the second value. This is the core essence of what a test is.

Karma

Karma is a command line test runner. It is the tool that actually causes the test to be executed. It is complex in execution but simple in concept.

· Karma launches the browser and then causes that browser to run your test.

· Karma can render test in mutiple browsers based on how you configure it.

· When finished, , it will report out the results of the test run to you.

CONCLUSION

In this article, I wanted to talk about what is Unit Testing and explain its basic concepts. If you want to start writing unit tests this article is great for seeing the test process and understanding the logic behind it. I hope it was helpful :)

--

--