Hello.
In this video, we're going to talk about a very common question from interviews.
Question 46.
What are mooks mocks are objects that pretend to be other objects, and they're used mostly for testing
purposes.
For example, we don't want to use a real database connection in unit tests, and we'll explain why
in a minute.
Instead, we will replace the object connecting to a database with a mock that provides the same interface,
but returns this data.
Let's say we wanted to test this glass emerging.
This method connects to our audio database, performing all necessary steps like opening the database
connection, executing some obscure queries, etc. The unit tests for this class could look like this.
This test simply executes the format method when this method will run.
It will try to connect to other database searching some people object and formatting them.
This test could even work under some circumstances, but there are numerous problems with this approach.
First of all, a test that connects to a database is not a you need to test.
A unique test should test only one piece of functionality.
Here we test the class, the database connection and the database itself.
Also, unique tests should be fast, and connecting to a database takes time.
This test only reads from the database.
But what if other tests would also write do it if some of test would add a new person to their database?
This test would start to fail as the result would contain one more line as this would run the database
state, with giant constantly affecting the results.
Because of that, we would be forced to reset the database to some desired state before each test,
which would again take significant time.
Also, what if the database is not set up on the computer of another developer?
This test may work for us, but it may not work for others.
Finally, what if the database contains millions of entries?
Then the result of the format method would be a normal string, which would obviously be problematic,
especially if the test failed.
And in this huge string, we would try to find the exact part that doesn't match the expected result.
To solve all those issues, we need a mechanism that will allow us to mock the database connection instead
of using an object connecting to our database.
We'll use a fake one that will return a predefined set of data used for testing purposes only.
But first, we must refactor this code to use dependency injection, so we are not tightly coupled with
the implementation that connects to a real database.
Here, I injected an object implementing open data reader interface to the production code.
We will use this implementation would actually connect to a database, but for unique tests, we'll
use AMOC.
I will be using the mock library for that, which is one of the most popular mocking libraries for C-sharp.
This is how we can create a mock up of some interface.
As you can see, I moved the creation of the cross under test object to the suck up method.
This is because I want a brand new mark for each test, which is a good practice since the mocks have
their own state.
They use it mostly to track what methods have been called upon them, which is used for validating behavior.
We'll talk more about it later in this sector.
Let's not use this mock in the test.
I will set it up to return some predefined people objects when they reach people.
Method it is gold.
First of all, let's make sure this test buses.
Great.
The dust has passed.
Let's make sure we understand what happened here.
I set up the mosque, so it returns this collection of people when the rich people method is caught
on this object.
This mosque was injected into grass under test object.
So when we called the format method on this object, this is what happens.
This object is actually a mock, and it doesn't connect to our database.
This method will return the collection I defined and it will be used when the people's data is formatted.
Finally, I simply compare the result with the expected result using a mock solved all problems we mentioned
before.
Now this test is a real.
You need to test it, test the personal data for model class in isolation.
It is fast because it doesn't connect to a database.
It has no way of affecting other tests, as it doesn't modified and the charts state.
If we had a test that doesn't use marks and it would write to a database, it would modify the database
content for all of our tests.
Also, this test will work on any machine.
No matter if some database is present on it or not.
Finally, we have full control over the data.
We defined a small set of people that is enough for testing the personal data, for matter.
We won't be affected by the fact that there can be millions of people in the database.
All right.
Please notice that mosques have one more powerful ability.
We can verify if some methods have been called upon them as part of the test verification.
Let's consider this class.
This class is quite simple, but unfortunately it is not easy to test the print hello and transmitted
is void.
So there is no result to be compared with the expected result.
The test of this method should basically have a way of checking if the whole thing was printed to the
console, given the amount of times it could possibly be done by actually running the program, which
of course, would make this test known unit and somehow intercepting the output printout to the console.
But these would be complex, tricky and non unitary.
After all, we would be testing the console class as much as the enthusiast in a greater class.
The solution is again to use mock.
But what do mock fear exactly?
Well, ideally it would be to mock the console class, but it is impossible since this class is static
in most frameworks, including mock.
The mocking mechanism is based on inheritance or on implementing some interface.
So a mock object is basically a derived type from the type we want to mock, or it implements the mocked
interface.
We can't have classes derived from static classes, so it's not possible to mock the console class again
willing to use the dependency injection.
I wanted to inject the logic of printing to the console.
Printing to the console is simply a method that takes some string so I can do it by passing an action
object to this class.
In the production code will simply inject an action that uses console pipeline.
This is how we could do it, but for testing purposes, we'll use a mock of the action object.
And now we can write a test that tracks that her offspring has been printed Usman at times as the number
provided with the parameter.
Here, I simply verify that the action mocked by this object has been called with this parameter.
Exactly five times.
Let's make sure this test buses.
Great, thanks to MOCS.
We managed to test a method which doesn't produce an output.
Instead, we tested that a specific method was called with a given parameter and a given number of times.
Let's summarize MOOCs are objects that can be used to substitute real dependencies for testing purposes.
For example, we don't want to use a real database connection in unit tests instead will replace the
object connecting to a database with a mock that provides the same interface, but returns this data.
MOOCs are an essential part of unique testing, and it's nearly impossible to test a real life application
without them.
During the interview, you can be asked What is mock?
Mock is a popular mocking library for C-sharp.
It allows us to easily create MOOCs of interfaces, classes, Funk's or actions.
It gives us ability to decide what result will be returned from the mocked methods, as well as validate
if somebody has been called.
How many times and with what parameters?
What is the relation between mocking and dependency injection?
The relation between them is that mocking is hard to implement without the dependency injection dependency
injection allows us to inject some dependencies across so we can choose whether we want to inject our
real implementations or mocks.
If the dependency of the class would not be injected but rather created right in this class as code,
we could not switch it to a mock implementation when we wanted to test this cross.
All right.
Let's eat a Botox.
Thanks for watching, and I'll see you in the next video.