When testing an API (with, for example, Java), what parts should I actually be testing when calling methods of my Controller class (e.g. a Spring RestController)?

For example, lets say I've got a logIn method in my controller. Said method calls some methods of another class (i.e. my Service class), ultimately returning a login token/session/...

Should I now only be testing whether the Response I send to clients is valid, i.e. contains correct headers, cookies, and so on - or, should I be testing whether or not the login token/session/other-thing-that's-made-by-the-service-class is valid as well?

(I'd imagine these tests would go in a separate class that specifically test my Service Class and it's methods (which generate my login token/session/...) - but even then, how would I go about mocking the user data that's needed to create my login token/session objects?)


Test functionality not implementation.

Testing implementation details kills refactoring. You can't change anything without breaking a test.

Correct headers, cookies, and token validity shouldn't be defined by the test. They should be defined by the code that creates them and uses them. What you test is if a user attempting to log in gets the response they should get when they do it right and when they do it wrong.

I should be able to refactor the way headers, cookies, and tokens are done without having to rewrite tons of tests. Tests should be able to quickly tell me if the different parts of the system have different ideas of what headers, cookies, and tokens should be.

Do not enforce implementation decisions with tests. Enforce agreement of implementation decisions on different operational code that must agree.

The only time I move away from this is when I don't have access to both sides of the code that must agree and am actually programming to a specification. Only then do I write tests that confirm the specification and I cite the spec in the test. That way it's clear why anyone should care what this test thinks.

  • Thank you for your detailed response. I agree with everything you're saying. However, does that mean that (except if creating a specification itself), testing response headers (like with Spring's mockMvc.perform or NodeJS' supertest package) is completely redundant? – rezadru Apr 27 '19 at 15:41
  • You may want to hold off on the tick for at least a day so you can gather more answers. Also, nothing I've said invalidates entire testing frameworks. The key is how you use them. – candied_orange Apr 27 '19 at 15:49

I advise creating an end to end test which uses a client to connect to your api as a user would.

You want to be able to point these tests at your live api and ensure its working.

There are always implementation details that can go wrong with the hosting layer, such as ports, firewalls, caching etc which unit tests on your service layer wont pick up

Not the answer you're looking for? Browse other questions tagged or ask your own question.