TDD with micro services

Asked

Viewed 246 times

3

I have two micro services one depends on the other, the micro service B depends on the A. I wrote tests for the A and for the B. The test of the A wheel does not depend on any other project, but the B tests need some actions that only the A can do. For example:

O INSERTS HER User and B makes the license plate of a User. Then it will be necessary to have a User at the base to perform a matriculation. Up to the moment I put an Insert script in service B to insert User, that is, the script simulates the actions that A would do, when I run the B test it calls the script that simulates service A, so I can run the B test without service A. But I don’t know if this is good practice, someone has been through this situation?

  • 3

    It’s more or less that, one of the reasons I don’t use both things, a lot of added complexity for little benefit. It has a good side, it’s fashionable.

  • But which solution do you use?

  • 1

    A simple one that doesn’t involve complicating your code, your architecture to stay fashionable. Do you need these things? Almost nobody needs them. But they talk so much that people feel obligated to use it. Almost nobody needs it. TDD done wrong, and almost everyone does, it’s only downside, MS in makes little sense, because either you have several micro applications naturally and don’t need to think too much about what to do, or MS adds too much complexity for little or no benefit. What alias your huge team should know how to handle it. Doesn’t it work on a team like this? It doesn’t make sense to use these things.

  • Hello Bruno! I don’t quite understand how the TDD enters this scenario yours. What kind of test are you doing: unit, integration, other? Tests depend on the other micro service in the air??

  • @Maniero can I give you some feedback? I saw you in other comments and responses "venting" a little about these and other subjects. I almost always agree with you, but I think this actually deviates from the purpose of the question and confuses users. I hope you take the feedback :), then remove here the comment

  • 3

    @Dherik yes, quiet, but what do you think I should do, just be quiet, like everyone else does, and let the person get stressed out?

  • @Dherik, I am testing web service, I mean, I am consuming the url s of the service B. However, to use the service B, I need registered users in the base, these users are registered with the service A.

  • @Maniero, the warning can continue, I believe only form could change. A tip would be to start the reply/comment by responding to the author and, at the end, adding the warning with the necessary details (since you want to give this message), preferably knowing her context: has she started the project now or not? Still time to change?. Many users come to the question with the same problem and want to see the solution first. For example, imagine that for any difficulty with React the first answer starts by talking to reflect its use and think about using only pure JS?

  • @Dherik but I answered nothing, I questioned in comment. If I wanted to reply I would have posted a reply, so I just commented, for this serves the comments.

  • @Maniero, but even in the commentary I think this creates some confusion. But I have an example answer too, in a user’s topic asking if his class UML was correct. He comments that he wanted to get out of the procedural form of code and think of OOP. Link: https://answall.com/a/311979/4492

  • @Dherik and what is your proposal? And what is the problem in the question?

  • @Maniero, I commented in my previous comment on the suggestion, but I took the liberty of answering the question of the link cited earlier to demonstrate what I meant :).

  • @Dherik is that your proposal only makes sense if it is an answer, I just commented. I then see your answer. Usually I go reading and answering the question sentence by sentence, if one puts at the beginning something I think I should talk about, I answer that at the beginning.

Show 8 more comments

2 answers

2

Best practice depends on the type of test, but it should be borne in mind that the mock is the answer to many problems.

You have the microservice To and the microservice B. Like B uses To, you create a microservice Am, which is the mock of the service To. It has the same API as the A service and maybe an extra API to configure, but its implementation is just a mock.

Unit tests will only use isolated classes of the module being tested and most dependents are mocked (mocking everything blindly can be bad, as I explain in that reply, it is necessary to know how to).

Already in microservice acceptance or integration tests B, should go up, beyond the service B, the service Am. So when the service B integrate with the To, who will be answering in truth will be the Am.

An example, taking into account your specific case, would be something like this:

  • The service To offers to Apis cadastrarUsuario and login.
  • cadastrarUsuario receives the user name and password and returns a token or an error.
  • login receives the user name and password and returns true or false.
  • The service Am has the same API as the service To.
  • The service To keeps everything in a database with long-term persistence and can connect with other services internally. The service Am keeps everything in memory while running, does not connect to anything else and loses all its data as soon as it is shut down.
  • The service B is responsible for conducting user registrations.
  • The tests of the service B in need of service B entire running, also go up the service Am.

Note that the only thing that is necessary for this to work is that To and Am should have the same API. However, sometimes (not always) it may be useful for you to have To and Am have in the largest possible extent, the same code, exchanging only an internal component to access the database.

In particular, the mock is very important when you will integrate with an external service (imagine that the service To is an API made available by a third party for which you have no control or knowledge about the implementation). In this case, it is very important you build a service Am to build and test your service B.

Finally, there are scenarios where you will need to do integration tests with the services B and To, mockless. The ideal is to avoid them to the maximum and minimize them whenever possible, but there may be situations where avoiding this can be difficult, costly or impractical.

1


Unfortunately there is no silver bullet to solve this kind of problem in tests.

Your solution works but is very intrusive to To, because to test the micro service B you need to know up to the micro service database To and insert information directly into it. It does not seem right that micro services are, by definition, independent.

Basically, the best possible scenario for you would be to start the micro service B and not worry about starting the micro service To (or C, D, E... ). Sometimes it’s possible, sometimes it’s not. It all depends on the environment you have available.

Usually, these are the options:

  • Connect the micro service B in a Wiremock instance that mimics all micro-service responses To. You can start Wiremock for this separate from any micro service.
  • In the micro service B, you can customize an implementation Fake of the code calling the micro-service To, including some basic rules, example: "If the CPF is X, I return the User". Thus, you can start the micro service B using a certain parameter that turns on/off this "mock" of the calling services To.
  • Connect the micro service B in a shared environment of instances where we will have the micro service To (or C, D...). Thus, you can use existing users in this environment to do their tests.

Depending on how your micro service To works and provides its functionalities, you can also:

  • Calling the micro service API To to create the users you need before starting tests on the micro service B. This alternative is more reliable than using a direct database script on To. I’ve seen automated testing this way in environments with all micro services in the air, but it only works well if there’s an API available for everything that needs to be done.
  • "Calling the micro service A API to create the users you need before starting tests on micro service B", this situation seems to me the most favorable. I can even put that kind of documentation information to run the tests.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.