TDD with micro services

3

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

O A enters User and B enrolls a User . Then it will be necessary to have a User on the basis to enroll. At 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 roll the B tests it calls the script that simulates the service A , so I can run the tests of B without service A. But I do not know if this is a good practice, has anyone ever been through this situation?

    
asked by anonymous 05.07.2018 / 16:33

2 answers

1

Unfortunately there is not a silver bullet to solve this kind of testing problem.

Your solution works but it is very intrusive to A , because to test the B micro service you need to know even the micro service database A and enter information directly into it. It does not seem right to me 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 A (or C, D, E .. .). Sometimes it is possible, others are not. It all depends on the environment you have available.

Usually, these are the options:

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

Depending on how your A micro service works and provides its features, you can also:

  • Call the A micro-service API to create the users you need before you start testing on the B micro-service. This alternative is more reliable than using a direct database script in A . I've seen automated testing this way in environments with all the micro services in the air, but it only works well if there's an API available for everything that needs to be done.
06.07.2018 / 13:33
2

The best practice depends on the type of test, but keep in mind that mock is the answer to many problems.

You have the A microservice and the B microservice. As B uses A , you create an Am microservice, which is the A service mock . It has the same service A API and maybe an extra API to be configured, but its implementation is just a mock.

The unit tests will use only isolated classes of the module being tested and most dependents are mockada (mockar everything blindly can be bad, as I explain in this answer , you need to know how to dosage).

B service acceptance testing or integration B service needs to be uploaded. So when the B service integrates with A , who will be responding will actually be Am .

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

  • The A service offers the cadastrarUsuario and login APIs.
  • cadastrarUsuario gets the user name and password and returns a token or an error.
  • login gets the username and password and returns true or false.
  • The Am service has the same API as the A service.
  • The A service keeps everything in a database that has long-term persistence and can connect with other services internally. The Am service keeps everything in memory while it is running, connects to nothing, and loses all of your data once it is turned off.
  • The B service is responsible for enrolling users.
  • The tests of the B service requiring the entire B service running, also go up the Am service.

Note that the only thing that is required for this to work is A and Am should have the same API. However, sometimes (not always) it may be helpful if you make A and Am as extensively as possible, the same code, to access the database.

In particular, mock is very important when you are going to integrate with an external service (imagine the A service to be 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 that you build an Am service in order to build and test your B service.

Finally, there are scenarios where you will need to do integration testing with the B and A services, without mocks. The ideal is to avoid them as much as possible and minimize them whenever possible, but there may be situations in which avoiding this can be difficult, costly or unfeasible.

    
05.07.2018 / 20:09