How to mock REST Services? - spring

I have a maven/mule/spring development environment that I build REST services within. I also have a series of TestNG tests to validate these services. I also want the ability to alter the responses from the services, either returning specific information or throw an exception. This was I can automatically test broader behaviours of the services. I figured that mocking the services would be the best approach, but I cannot find any good information on how to mock a REST service.
Is there any material I can review on how to mock a REST web service?
--Update---
I thought I would add an example to make the problem more concrete. If I have the following setup:
testA calls serviceA, which then calls serviceB
If serviceA should return a web exception to testA if serviceB responds with an error, I would like to inject a mockedServiceB in to the system for the test where mockedServiceB always returns an error:
testA calls serviceA, which then calls mockedServiceB (which always returns an error to serviceA)

Generally speaking I would fragment my Mule configuration to have one service per fragment then load real service A fragment and a test service B fragment at test time. Test service B would use the Mule test:component to simulate good or bad returns.

I had the same problem and wrote a small lib for mocking REST services: https://github.com/mkotsur/restito.
You can give it a try.

Related

Seperate wiremocks QuarkusTestResources

In my Quarkus application I have multiple controllers which use multiple rest clients. I have multiple tests which all use a #QuarkusTestResource with a Wiremock resource. My approach was for each controller to have it's own Wiremock resource and stub whatever restclients they need and how the stubs needs to be defined. So each test might stub out the same rest client but with different stubs.
When running my test I found that even if each test class is annotated with a different Wiremock implementation they overwrite each other it seems like. The tests are probably run in parallel and the configuration (/mp-rest/url) is shared between them and overwritten by the QuarkusTestResourceLifecycleManager that ran last.
Any tips on how to solve this? Or should I just create one Wiremock class for each rest client?
I think you can use restrictToAnnotatedClass in QuarkusTestResource for that. It is available in at least Quarkus 1.13. See: https://quarkus.io/guides/getting-started-testing
You can also use
wireMockServer = new WireMockServer(new WireMockConfiguration().dynamicPort());
to define a dynamic port to each WireMock server

Unit testing for Spring Boot API

I'm developing a Spring Boot Web API, and I'm currently writing the required units tests.
I was wondering : Isn't writing the units tests (JUnit + Mockito) for the controllers sufficient ? Since the controllers are the entrypoint of my application and that all the logic that is implemented within the Service side is called from the exposed API, why do I need to write test for the Service side ?
First of all, if you write your tests to cover "required level of tests" or requirement to "have some tests at all" having the production implementation already done, it is slightly too late. In the majority of cases having tests first, based on your requirements, contract, use case or anything it more optimal approach. Nevertheless, I don't know your situation and the thing you're trying to implement, so treat it as a suggestion and move on to the key thing you are asking about.
Your JUnit (preferably 5) and Mockito tests, which probably use MockMvc are very good unit(-like) tests to cover web communication concerns such as: HTTP request types, content type, encoding, input and output parameters JSON (de)serialization, error handling, etc. They are best to test with the service layer mocked. Thanks to that you can easily cover a lot of web cases without the need to prepare data in a database, etc.
The core logic has to also be tested. Depending what it is, it might be feasible to test it in the unit way (the easiest to write, can cover a lot of - also corner - cases). It could be supplemented with some set of integration tests to verify that it works fine also in integration (Spring Beans, DB, etc.).
If desired, you may also write some E2E test from the web call via (real) HTTP requests through controllers, services to a database/datastore (if any), but I would limit it only to the most important scenarios to use it in your CI/CD pipeline to verify that a deployment finished successfully.
Disclaimer. I've found this approach useful in multiple situations, but definitely in some other circumstances it might be good to change the balance point to better apply testing.
I think you are probably getting confused between unit and Integration tests.
If you are using Mockito you are probably referring to unit tests wherein, the scope of the Test Class should be only the current class.
Any external method calls should be mocked.So in your case the service calls should be mocked in case you are writing unit test for your controller class.
Your Test Suite should contain
Junit for Controller-- To Test the interface contract points like HTTP Method, Request Parameters, Mandatory inputs, Valid Request Payloads.
Junit for all other classes including Service classes- This is to test your application classes core logic
Integration Test- Finally an integration test which can hit your controller endpoints with service classes and rest of the application code functionality.

spring rest doc - service layer mocking

recently i saw the blog post say that "for documentation purpose, we use mocking for service layer (in environment using spring rest doc)", so this post use annotation like spring's #MockBean to service layer object.
but i think, if i mock service layer -> spring rest doc always success to test because mocked service object always return intended result and spring rest doc test always receives same intended result from mocked service object.
so i think that is not right but,
i want to know about what is better or how you use service object with spring rest doc
pleas answer
Whether or not it's a good idea to mock the service layer when using Spring REST Docs is largely down to personal preference.
A possible disadvantage of mocking the service layer is that it may be possible for the documentation to get out of sync with the service's actual behaviour. This undermines REST Docs' ability to help you to keep your documentation and service in sync.
An advantage of mocking the service layer is that it can make it easier to document error scenarios or scenarios that would otherwise require quite a lot of setup. In the case of errors, I think you are better adopting a common approach across your whole API and making consistent use of standard HTTP error codes. If you do this, the need to document error responses for each endpoint in a service is reduced.
This leaves documenting more complex scenarios that require a lot of setup. In this case, limited use of mocks may be worthwhile but I would still aim to produce as much of your documentation as possible without relying on mocks.

Unit testing in spring mvc

If I want to unit test my dao classes in spring would I just call my service methods and test those or would you test the service methods separately to the actual dao methods?
Also should I mock the dao calls or actually use an in memory database like H2? I see that as more of an integration test although some tutorials do this, or would a standard approach be to test with mock database objects for the service tests and use H2 when testing the dao calls?
Finally.. My application has a rest API which is called from the web front end using the Spring rest template and so only the API web app accesses the database.
Would I test the rest methods in each web app using mocked objects and then Start a tomcat instance and integration test between the 2 apps? If I used tomcat and ran integration tests between the apps would connect up a database or mock objects in the API app?
Testing the rest calls from the web app relies really on how the API app's rest method responds so is this even worth testing in isolation?
I find unit testing quite confusing as some of it seems almost to be integration testing.
Does it matter if you run integration tests against H2 in memory but then in reality I would be using MySQL?
Trying to answer your questions in the order asked...
For unit testing DAO methods, you should test the actual DAO classes directly with a database in a known state. H2 is great for this, since you can run it without setting up MySQL for each test. Utilizing setup methods with the #Before annotation is great to make sure that the database will respond in expected ways.
For unit testing Service classes, you should mock the DAO classes, so that they will always behave in expected ways. If you use your service and DAO classes with actual data, you are now running integration tests, by testing multiple layers simultaneously. Both have their value, though is generally best to unit test before integration testing, to make sure each component is functioning.
The same goes for testing your controller, you should unit test it and mock the service classes, and then perform integration tests with mock requests to test request/response scenarios. Again, with this test setup you are now testing many layers and classes simultaneously. This is great, because it gives you a good idea of how your application will function in reality, but is not useful for isolating bugs.
H2 and MySQL obviously are not the same, and don't share all the same functionality, so you can't say with 100% confidence that an H2 test will pass in MySQL, but if you are just testing standard CRUD operations, it should do the trick.

Mocking AOP method implementation for unit tests

I've a java application which has multiple modules - (GWT-)RPC services, perf-library, remote-client (All java code written/owned by my team). The perf-library contains Spring AOP aspects related code and it's primarily used to push intercepted method logs to a data store. Now, perf-library is dependent on another remote-client which actually maintains a queue and handles the job of pushing logs to the data store. So, in a way, perf-library just delegates the task to remote-client.
The business logic code calls intercepted methods which have AOP logic and hence there is a dependency on remote-client. Obviously, I don't want to connect to the remote-client from within unit tests. I think I need to mock the implementation of method push() which connects to remote-client. What I'm unable to figure out is how to use the mock implementation for the business logic code package unit tests.
To clarify things, I've modules like this -
RPC service module - e.g. method login() is intercepted.
perf-library - Has aspects (to intercept methods like login()) and implementation to call remote-client
remote-client - Push data to some data-store
Now, for writing the unit tests for RPC service methods, how do I get the mock implementation of push() as it is internal to perf-library. Let's say, I've an interface LogClient (having method push()) which is implemented by two classes (one for production and another for test). I can use this Test implementation for unit tests of perf-library itself, but how do I make the RPC unit tests use it. I'm new to Spring, so not sure if this can be done easily with Spring or anything else. Any help will be nice.
Note: We're using Spring for maintaining beans and DI.
Not sure exactly how but Mockito can be a good choice.
Check this link for details.

Resources