Spring integration testing for REST call of some other Service - spring-boot

I've been searching it on the net , but most of the examples i found have the returning logic of rest call within the same project , but what if you want to test a rest call of some other service which you are using it in your project(calling a REST api from a REST API)
is there any way to integrate this . Integration testing for a REST call which is of some external service
can the normal Integration testing approach could work in this case.

Have you considered using Spring Cloud Contract (http://cloud.spring.io/spring-cloud-contract/) ? It's a project design specifically for that purpose.
You have the producer of the API and its consumers. The idea of Spring Cloud Contract and Consumer Driven Contract approach is such, that the consumers suggest how the API of the producer should look like. They can prototype the API without writing any production code on the producer side. The prototyping takes place in a form of a "contract". It can be a Groovy or a YAML file (you can of course extend the framework). Processing of the contract results in a creation of a WireMock stub that the consumers can leverage in their integration tests. In other words, it's as if the producers would prepare a small, fake implementation of their code for testing perspective. So the consumers can run their integration tests against a stub of the producer side. The stub was generated from the contract. Let's say that the consumer X wants to use an API in such a way that if a GET request is sent to /foo it will respond with text bar. Then a stub that responds with a bar text, when hit at the /foo endpoint will be generated.
Now, the producers reuse the same contracts to generate tests to verify if their API meets the requirement of what's there in the contract. Remember the GET # /foo will respond with bar example? If the producer tries to build its project and doesn't have such an endpoint, its build will be broken. The Spring Cloud Contract framework generates the tests that assert whether the API is working the way it should. Only after the producer fixes the missing implementation will the build pass.
This is the consumer driven contract approach. You can also do the producer driven approach where the producer of the API just defines the contracts without communicating with the consumers how exactly each of them is using the API.
Valuables links:
Spring Cloud Contract page: http://cloud.spring.io/spring-cloud-contract/
Spring Cloud Contract workshops: http://cloud-samples.spring.io/spring-cloud-contract-samples/
Contract Tests in the Enterprise presentation: https://www.youtube.com/watch?v=ZyHG-VOzPZg
Why Contract Tests matter presentation: https://www.youtube.com/watch?v=TvpkZu1e2Dc
Note: I'm the maintainer of Spring Cloud Contract.

Related

Integrating hundres of SOAP services - Spring boot

I have a system (kind of aggregator) that integrates with hundreds of different SOAP services - most of them do the same business functionality, but each service having different data structure in SOAP request & very few having 2 API calls to complete one transaction.
The present service integration workflow is
create stubs from WSDL
map data to the generated stub api
setup a new endpoint to fire this api
I see this a repeated, unintelligent work & requires development effort for every new service integration.
Was there different approaches to integrate with lot many systems? Any libraries that can generate soap requests based on configurations, or I have to rely on some Java SOAP, Spring lirbaries to create custom SOAP xml request from my own configurations? I see Spring's WebServiceGatewaySupport for webservice client but requires stubs created from wsdl?
Is it wise to define soap request xml as templates for every service, generate xml with input data?
Other ways I thought was to develop each integrations as independent microservice layered under an API gateway that routes each requests to specific service. But this design approach will have hundreds of services running, consuming more resources (in case of Spring boot).
Generate stubs & deposit the jar to disk, load this jar with a classloader & use the stubs using reflection - not so simple, I believe.
Use of serverless looks promising but is not possible immediately.

Testing REST API provider response without mock

Currently, I am working on a project on Spring Boot where we are integrating with external REST API. As part of our integration suite test, we are doing the mock test of the actual external API which executes as part of the CI/CD.
My question is in production it calls the actual API so, how we can do that in the test environment. I don't think we need to make the actual external provider call during multiple integration test which will load the external API, also at the same time would like to test with actual REST response from the service.
Any suggestions?
If the public API has a swagger description, you could use the Atlassian Pact Swagger Validator. I describe the workflow in this talk: https://www.youtube.com/watch?v=79GKBYSqMIo#t=39m10s
Another alternative would be to create a mock API for the external service. There are some free services like https://mockfirst.com, https://www.mockable.io/, etc. where you can do that.

Stub for Feign client for integration testing

I have a spring cloud project with the following packaging structure
Controller (publishes Rest Endpoint)-->flow (business logic)-->service (calls Feign client with hysterix fallback setup )--> Feign client.
Auto-wiring is done in respective classes e.g. flow is auto-wired in controller and service is auto-wired in flow and so on.
I want to perform integration test, by calling the endpoint published by the controller. The problem is I don't have endpoint accessed by the feign client at the moment (neither original nor spring cloud contract stub is available).
How do I stub the call made by feign client in this case.
You can use Spring Cloud WireMock support and set up an endpoint manually before the tests are called. In the feign configuration you can point manually to an IP and port. The problem is that this test is pretty much useless cause as a consumer you're mocking the producer.
UPDATE
You have a Feign client that will be used to call some external API. What you can do is you can use Spring Cloud WireMock (or just WireMock) to setup a mock of that API. Then you can teach WireMock to behave as you wish and assert whether your client works fine. The problem with such an approach is such that since you, as a client, are setting up the WireMock instance, you can teach it to behave in the way that has nothing to do with the real API. For example you state that if you send a request to endpoint /foo with a method GET then you should get back "BAR" in the response. Then you write a test where your client sends GET # /foo and assert that BAR got properly returned. However that doesn't mean that the other API indeed has that endpoint. So this approach can give you false-positives. You can however use WireMock to assert whether you can properly react to faulty responses like malformed response etc.
In such cases, if you really want to check if you can communicate properly with an API that you don't control, is that you can write tests that will call that real API via a WireMock proxy, you record that traffic and convert it into stubs. You can watch about this more in my presentation here https://www.youtube.com/watch?v=ZyHG-VOzPZg

Spring Cloud Contract testing without Spring Framework (Boot)

I would like to know if it is possible to use Spring Cloud Contracts with other frameworks not only Spring Boot? An example of another framework I'd like to test Spring Cloud Contract is KumuluzEE.
Are you asking about the consumer side or the producer side?
On the consumer side you can use the JUnit rule (http://cloud.spring.io/spring-cloud-static/Edgware.RELEASE/multi/multi__spring_cloud_contract_stub_runner.html#_stub_runner_junit_rule) .
On the producer side you can use the EXPLICIT mode (e.g. http://cloud.spring.io/spring-cloud-static/Edgware.RELEASE/multi/multi__contract_dsl.html#_working_with_context_paths).
That way the generated tests will assume that you're sending a request to a real running application. So in the base class (or before even running these tests) you'd have to start your app and then point to the URL (like here https://github.com/marcingrzejszczak/the-legacy-app/blob/master/stubs/src/test/java/com/example/contracts/BaseClass.java#L15)

Spring Integration Webservice vs. RestTemplate

I'm trying to learn SI (Spring Integration) but i'm a bit confused on the real usage of this.
As first example i would like to interact with a WebService but i dont understand what could be the difference from
Invoke a WebService Using SI
Invoke a Webservice using RestTemplate
So, what is the benefit of using SI (in Webservice context, or in other context)?
Looking the web, i havent find an article that explain:
Usually you will do in this way....
With SI you can do better - in this another way - and the benefit are....
To be more explicit on what i have to realize, this is an example:
1) I have to write an application (Standalone application) that have to collect some data in the system periodically and then invoke a Web Service that will store it.
2) The Web Service receive the call from the "clients" and store in the database.
My webservice will use REST.
The reason because i've think to use SI is that the Standalone Application should interact with different system
Webservice in first instance
A Web Mail, if the webservice is not achievable
File system if Web mail is not achievable too
If you only need to pull some data in a simple way and push it onwards to a REST service this does not "justify" the use of Spring Integration. A simple Spring (Boot) application combined with a scheduler will be sufficient.
But if you want to use a more complex data source for which an endpoint is available, you need transformations, complex and flexible routing is a high priority or even Enterprise Integration Patterns (EIP) then Spring Integration is for you. Have a look at the Overview and decide if it mentions something you consider as valuable to you.
Perhaps you will create additional value by mixing in Spring Batch if you need to process a lot of data.
But as I understand your current demand starting with just a RESTTemplate should do for the moment. Starting small will not prevent you from switching to Spring Integration later on.
Have a look at the various tutorials and guides provided by the Spring Boot project. There is even an example for Spring Integration.

Resources