Springboot test custom client, controllers and/or filters – a quick way

Recently I posted a question to the stackoverflow (please check it out first). Unfortunately I didn’t have time to explain – ‘why?’

Also I don’t think stackoverflow allows lengthy debate in the comment section. So I would like to make a quick explanation and hopefully have a debate in the comments.

Ok, so, why would you want to test service client and associated controller (springboot service) in the same unit test? I believe the case is fairly narrow and following conditions should apply:

  • Microservice must come with an associated client, which is capable of executing all available endpoints (in my case: internal microservice policy)
  • Client is complex!
    • Serialization and deserialization of objects
    • Uniform handling of errors (internal errors)
    • Custom security (internal use)
    • Custom compression
    • Logging
  • Controller is thin (just a delegation to a business layer)
  • Limited/Inflexible build pipeline OR time constraint on unit test execution (let’s say if test takes more than 4-5 seconds)

Now here is a list of ‘usual suspects’ to why NOT test client and controller together:

  • Service and client are separate ‘units’ therefore SRP and/or separation of concerns
  • Client is simple and can be tested separately
  • Controller can be tested separately
  • Fast/flexible build pipeline and/OR no time constraint

I would like to defend my approach:

  • Unit test is very flexible term – I believe developer/business can define what unit actually means. In my case, internal policy states that if I develop new endpoint and/or service I must provide a client, that will comply with company’s internal needs. So a unit of work in this case is client and associated endpoint/s, one can’t exist without the other – therefore one unit.
  • Client is not simple at all. Luckily most of the internal logic is abstracted away, so I can reuse abstraction and focus on immediate things like: path params, path variables, method and payload – which should be tested.
  • Controller in my case is thin one – meaning there isn’t much code there, typically one line – delegation to business layer. So I can test controller separately, but there isn’t much value. The value of the thin controller is in correct delegation and entry point (paths & params specified correctly).
  • Build pipeline is important tool, however if it is slow, constrained and inflexible, it becomes major source of headache (and sometime creativity). If your test brings up service and in process takes up a port and 10-18 seconds to start up, well the test will be ignored/removed in the name of performance – no value in that.

I hope this reasoning (along with stackoverflow solution) will be useful and helpful for those in need. Please share your thoughts.

Thank you!