What is TDD and Automated Unit Testing Part 3
Posted by 2/04/2018 01:27:00 PM with No comments
on This is a part from a series dedicated to TDD and Automated Unit Testing. I will try to do my best to keep this series alive and updated.
The series parts:
What is TDD and Automated Unit Testing Part 1What is TDD and Automated Unit Testing Part 2
What is TDD and Automated Unit Testing Part 3
On the previous part of this series we were trying to dive
in TDD and the world of automated unit testing and have a look on the best
practices and the new habits you should gain, abide to and embrace to be able to
keep up with that world.
We covered topics like:
- Single Responsibility Principle
- Inversion of Control (Ioc) / Dependency Inversion Principle
- Dependency Injection Technique
- Stubs
On this part we are going to discuss some important concepts
and expressions you will for sure come across while diving in the world of TDD
and automated unit testing.
So, the first thing to start with is “Mocks”.
What is Mocks?
As we have seen in the previous part of this series, we can
use “Stubs” to have full control on the subject (class/method) we are testing.
The main idea behind a “Stub” is to have a fake implementation of some
dependency on which our subject depends. This provides us with a chance to
isolate the subject from any other dependencies to make sure we are testing
only the subject, not it’s dependencies as well. This way, whatever the results
we get -a passing or failing test- we are sure that these results are triggered
only by the subject and that’s what we are trying to do in the first place.
For “Mocks”, the same concept and the same goal is applied
but with a different way of implementation. With mocks we don’t provide a full fake
implementation of the dependencies, we just add some hooks on the abstractions
of these dependencies and manipulate their behavior and adapt them to our needs.
It’s like creating a stub with minimum effort and on the fly.
I know these words are not self-explanatory and that’s why
we need to dive in more and see some examples of using mocks. But, before doing
that let’s add an extra note. Mocks are usually applied using some third-party
libraries, sure we can implement our mocking library ourselves but this is not
the best thing to do, I would rather prefer to use one of these libraries because
they are tested and used on too many projects and this is a great advantage if
you ask me.
Now, enough with the talking and let’s see some examples.
“Mocks” examples
I thought about providing here some examples and code
samples for using Mocks but I found out that these examples could be redundant
and sometimes misleading if they got outdated. As I told you before, usually
mocks are implemented using some third-party libraries and these libraries change
from time to time due to updates and bug fixes. Also, the syntax and way of
setup of each of these libraries is different and the knowledge of one of them
might not work with another.
So, the best thing to do to see some examples is to check
the documentations and code samples provided by these libraries son their pages
and repositories.
For example. You can check the well-known “Moq” library for the
.NET framework on its
GitHub repository. It includes all kinds of examples and samples you may
need.
Also, if you are a client-side developer, you can also apply
TDD and automated unit testing using frameworks like Jasmine. Jasmin also has
its own way of applying mocks, this way is called “Spies”. Using the “spyOn”
method you can achieve the same results you get using the .NET “Moq” library.
If you want to have a look on some samples you can search the
internet and you will find some results like this and this
and many others.
Why to use “Mocks” when we have “Stubs”?
In most cases you would prefer to use mocks instead of stubs
because as you can see that the amount of code, effort and time you need to
achieve the same result using stubs would be significant and this is logical as
with mocks you may implement only the portion you care about and it differs
from one situation to another. On the other hand, with stubs you need to
provide full implementation.
Also, one of the main differences is that with stubs you
will have to create some stub classes and these classes will end up on some
code file. I believe that this is not the best thing to do as these code files
will pollute the entire solution with some code unrelated to the main business
logic and its unit tests.
Also, due to the significant amount of code provided for a
stub, it would be more probably to need to get back to the stub and apply some
changes whenever the business logic changes and some changes are applied on the
subject itself.
That’s my own point of view, you don’t have to abide to it
but you can verify it.
So, why use Stubs at all?
Sometimes implementing a mock would be so difficult and
challenging. In this kind of cases we can implement a Stub that handles all
what we need and the implementation could be quite simple and easy. So, it is a
compromise, you should trade something for another but at the end you will have
a working solution.
Ok, that’s it for this part and I wish there would be coming
parts where we would see some examples and practices.