TDD: .NET, following the principles of TDD, Mock / Not to Mock?

I am trying to follow TDD and I ran into a little problem. I wrote a test to insert a new user into the database. Insert a new user is called in the MyService class, so I went ahead and created mytest. This failed, and I started implementing my CreateUser method in my MyService class.

The problem I am facing is that MyService will go to the repository (another class) to perform the database insert.

So, I decided that I would use a mocking structure to mock this repository class, but is this the right way?

That would mean that I would have to modify my test to actually create a layout for my user repository. But is it recommended? At first I wrote my test and made it unsuccessful, and now I understand that I need a repository and I need to mock it, so I need to change my test to serve the mocking object. Smell a bit?

I would like some feedback here.

If so, when will I create a real user repository? Will it need its own test?

Or should I just forget the mockery of something? But then it will be classified as an integration test, not a unit test, as I will test MyService and User Repository together as a unit.

I lost a little; I want to start the right path.

+4
source share
4 answers

So, I decided that I would use a mocking structure to mock this repository class, but is this the right way?

Yes, that’s the right way, because you have to test your classes in isolation. That is, by bullying all addictions. Otherwise, you cannot determine if your class or any of its dependencies.

I wrote my test initially and made it unsuccessful, and now I understand that I need a repository and I need to mock it, so I need to change my test to satisfy the distorted object. Smell a bit?

Class extraction, reorganization methods, etc. - this is refactoring. And the tests here will help you in refactoring to eliminate the fear of change. This is quite normal if you change your tests. I suppose you didn’t think you could create the perfect code on the first try and never change it again?

If so, then when will I create the actual user Repository? Will it need its own test?

You will create a real repository in your application. And you can write tests for this repository (i.e. check to see if it calls the underlying data access provider to mock correctly). But such tests are usually very laborious and fragile. So, it’s better to write some acceptance tests that implement the entire application with real repositories.

Or should I just forget the mockery of something?

Quite the opposite - you should use mocks to test classes individually. If bullying requires a lot of work (access to data, ui), then do not scoff at such resources and do not use real objects in integration tests or acceptance testing.

+6
source

You probably scoff at database dependency, and then claim that your service calls the expected method on your layout. I thank you for trying to follow best practices and urge you to stay on this path. As you now understand, as you move forward you will begin to add new dependencies to the classes you are writing. I highly recommend that you execute these dependencies from the outside, as in creating the IUserRepository interface so that you can mock it and pass the IUserRepository to the constructor of your service. Then you save this in the instance variable and call the methods (i.e. _userRepository.StoreUser (user)) that you need. The advantage of this is that it is very easy to satisfy these dependencies from your test classes and that you can worry about instantiating your objects and managing the life cycle as a separate issue.

tl; dr: create mock!

+1
source

I have two sets of test libraries. One for UnitTests, where I mock things up. I am only testing units. Therefore, if I had the AddUser method in the service, I would create all the layouts that I need to check the code in this particular method. This gives me the opportunity to check some code codes that I would not be able to verify otherwise.

Another test library is for integration tests or functional tests, or whatever you want to name. This ensures that the specific use case. For instance. Creating a tag from a web page will do what I expect from it. To do this, I use the sql server that comes with Visual studio 2012, and after each test I delete the database and start over.

In my case, I would say that integration tests are much more important than unit tests. This is because there is not much logic in my application; instead, it displays data from the database in different ways.

+1
source

Your initial test was incomplete, that's all. The final test will always deal with the fact that the new user continues to remain.

TDD does not determine the type of test you should create. You should choose in advance if it will be a unit test or some kind of integration test. If it is a unit test, then the use of mixing is almost inevitable (unless the unit under test has no dependencies for isolation). If this is an integration test, then the test should take into account the actual access to the database (in this case).

Any kind of test is correct. The general wisdom is that a larger unit test set is created, testing the units individually, while a separate but smaller set of tests uses the scripts of the entire script.

0
source

Source: https://habr.com/ru/post/1488124/


All Articles