Search code examples
javaunit-testingspring-bootmockitosystem-testing

How to system test with Mockito? Should we?


My project includes various of spring boot @Services which use third-party APIs.

We've written a mocked class for every such service and we run the system test in such way that Spring Boot chooses the mocked classes rather than the real ones (using @Profile("test")).

The motivation for that was:

  1. Test only logic (even though this can be done with unit-tests)
  2. Test empirically the system is thread-safe
  3. We can't use extensively our APIs (rate limits), but we want to run our system on a sufficiently large amount of items.

My questions:

  1. Would you advocate this approach for a system test? (all components are mocked)
  2. If so, can a mocking framework like Mockito do that? The whole point of Mockito is not writing the mocked classes on your own, but how can it be accomplished for a system test where a service is used by multiple beans?

Solution

  • This is a good approach for unit testing your services, by mocking their calls to the external services. You may want to separate your tests into unit tests and integration tests. Typically, unit tests mock any external service calls by using stub classes with @Profile (as you've done) or by using a mock library like mockito and you mock the return value of the service.

    In an integration test, which would be a better system test, you would use stub files that are served via a Controller or a mocking library (i.e. WireMock) that "mocks" the response of the external service. If your external API returns JSON, you could have a Controller or mocking library serve the actual JSON response. By doing this, you're testing that your service actually makes the API call and does stuff with your stubbed results. Instead of your service calling the actual API URL, you would have it call your controller or WireMock URL.