Test a spring boot microservice that needs to call another microservice - unit-testing

I have followed this tutorial to create an e-commerce microservice architecure (in french) and now I am trying to write some tests. My architecture is composed of 4 microservices with Eureka and Zuul:
A product microservice that is here to provide a list of products
An order microservice that will handle the orders
A payment microservice that will handle the payments
A client UI
The payment microservice have to call the orders microservice to check if the order has already been payed or not. And this is what I can't reproduce to write unit tests. I would like to test this microservice without launching the orders microservice.
How can I test it without launching orders microservice?
I already wrote some tests for orders microservice and products microservice.
Here is the payment Controller:
/*
* Operations to save a payment and notify the orders microservice to update the status of the sayed oreder
**/
#PostMapping(value = "/payment")
public ResponseEntity<Payment> payAnOrder(#RequestBody Payment payment){
// We verify if the order has been already payed
System.out.println("We verify if the order has been already payed");
Payment existingPayment = paymentDao.findByidOrder(payment.getIdOrder());
if(existingPayment != null) throw new ExistingPaymentException("This order has already been payed!");
// We save the payment
System.out.println("We save the payment");
Payment newPayment = paymentDao.save(payment);
// if the DAO return null, there was a problem when saving the payment
System.out.println("if the DAO return null, there was a problem when saving the payment");
if(newPayment == null) throw new ImpossiblePaymentException("Error, impossible to establish the payment, retry later!");
// We retrieve the order corresponding to that payment by calling orders microservice
System.out.println("We retrieve the order corresponding to that payment by calling orders microservice");
Optional<OrderBean> orderReq = microserviceOrderProxy.retrieveOneOrder(payment.getIdOrder());
// orderReq.get() extract the object of type OrderBean from Optional
System.out.println("orderReq.get() extract the object of type OrderBean from Optional");
OrderBean order = orderReq.get();
// We update the object to mak the order as payed
System.out.println("We update the object to mak the order as payed");
order.setOrderPayed(true);
// We send the object updated to the orders microservice to update the order's status
System.out.println("We send the object updated to the orders microservice to update the order's status");
microserviceOrderProxy.updateOrder(order);
// We return 201 CREATED to notify the client that the payment has been registered
System.out.println("We return 201 CREATED to notify the client that the payment has been registered");
return new ResponseEntity<Payment>(newPayment, HttpStatus.CREATED);
}
I am blocked at the step where we retrieve the order corresponding to the payment because it tries to call orders microservice but its not running!
Here is the entire code: https://github.com/kamal951/POC_microservices

You can easily mock the other microservices you are calling in your unit test. In Mockito (which is bundled in spring-boot-starter-test), you can do this with the following approach:
public class PaymentControllerTest {
private PaymentController controller;
#Mock
private MicroserviceOrderProxy microserviceOrderProxy;
... other mocks here
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
controller = new PaymentController(microserviceOrderProxy, ...);
}
#Test
public void exampleTest() {
Mockito.when(microserviceOrderProxy.updateOrder(Mockito.any())).thenReturn(--mocked result here--);
...
}
}

Related

GCP Pub/Sub: How to get event details in onFailure() of PublishCallbackListener

We want to have the fail back mechanism in case of any failure to publish event to Pub/Sub. I am using "ListenableFutureCallback" to know message published successfully or not. In case of failure, it is just throwing exception and I need event details to post it to internal messaging service. How do I get event details in onFailure() method.
I am using Spring Integration.
Below is piece of code.
Listener:
#Component
public class PubSubOperationListener implements ListenableFutureCallback<String> {
private static Logger LOGGER = LoggerFactory.getLogger(PubSubOperationListener.class);
#Override
public void onFailure(Throwable throwable) {
LOGGER.error("Failed to publish the message and details : {}",throwable);
// Logic to process it using different approach.
}
#Override
public void onSuccess(String s) {
LOGGER.info("Message published successfully.");
}
ServiceActivator:
PubSubMessageHandler pubSubMessageHandler = new PubSubMessageHandler(pubSubTemplate, testTopic);
pubSubMessageHandler.setPublishCallback(pubSubOperationListener);
return pubSubMessageHandler;
Please suggest if there is different approach to do same.
Currently, it's not possible because Spring Cloud GCP simply delegates to the Pub/Sub Publisher in the client library.
However, when we wrap the Future provided by the Publisher in Spring Cloud GCP, we can potentially include the original message there and other metadata. This would be a feature request that should be filed here.

How to handle network down when calling a API

Today, I am thinking a simplified scenario as follows:
I have my own payment system and when user come to save money, I use a form to save transaction data in my own DB. Before saving my own record, I need call Bank payment system which has a Webservice API like
public boolean pay(userInfo userInfo, float money).
Based on the result returned, I determine whether save my own data or not.
My question is if after calling the Bank payment API, my own network is off, and no result back. How to determine whether I need to save my own Form record or not. Maybe bank payment system has already processed this transaction? How to make two part data synchronized?
We cannot change bank payment API because bank spec is fixed. Webservice API is SOAP or Restful
Your implementation may be something like this:
Always save transaction data to your database and mark it as "unprocessed".
Use separate "worker" process, that fetches all unprocessed transaction from your database, and calls pay method of Bank payment system.
Accordingly to pay method result, choose to change/not change the status of the transaction.
Worker may by a scheduled process (each XX sec/minutes/etc) or some service that queries unprocessed transactions constantly (maybe with some delay between loops).
So in case of "no result" from Bank payment system, transaction state will not be changed and "pay" method will be retried on next worker run.

Grails 2.4.4 Testing for permission where spring security code is being used

I am using spock for may application testing and using Grails 2.4.4. I have done domain, controller, and service unit testing. But in controller sections I am stuck with the role wise access. For authentication I am using Spring Security Core Plugin. Below is my sample code.
#Secured(["IS_AUTHENTICATED_FULLY"])
def index(Integer max) {
}
#Secured(["ROLE_A","ROLE_B"])
def create() {
respond new DomainName(params)
}
#Transactional
#Secured(["ROLE_A","ROLE_B"])
def save(DomainName DomainNameInstance) {
}
How do I test that only the user with ROLE_A and ROLE_B can create and save and other cannot? Also I do I check the user is IS_AUTHENTICATED_FULLY to access index action ?
From your question, it sounds like you are trying to test whether the Spring Security code is working. My take on unit testing controllers is that 'if I didn't write I'm not testing it.' Services used by my controllers are mocked, configuration values used by my controller are mocked. Likewise, Spring Security behaviors are mocked (in effect). This means accepting some amount of risk related to the plugins that you use in your application. Do you trust Spring Security to handle roles and authorities correctly? I generally do.
I'm more interested in the behaviors of my code, so I generally just bypass the spring check in my Unit tests. If you want to verify the behaviors of your application if the user is or is not logged in, or does or does not have a certain role, you can do that.
def "test create method without required role"() {
setup:
// tell Spring to behave as if the user does not have the desired role(s)
SpringSecurityUtils.metaClass.static.ifAllGranted = { String role ->
return false
}
when:
controller.index()
then:
// without the required role, what does the controller return?
controller.response.status == ??
cleanup:
SpringSecurityUtils.metaClass = null
}
def "test create method with required role"() {
setup:
// tell Spring to behave as if the user has the required role(s)
SpringSecurityUtils.metaClass.static.ifAllGranted = { String role ->
return true
}
when:
controller.index()
then:
// with the required role(s), what does the controller return?
controller.response.status == 200
controller.response.mimeType.name == "application/json"
controller.response.getText() == "whatever"
cleanup:
SpringSecurityUtils.metaClass = null
}

list in j2me client stub

I create a web service that interact with database by hibernate.
the problem is:
when i want to create J2ME client stub, i receive some error(Unsupported tag in element jobs),
and i see my code and i found why that happen (it happen because in my Jobs entity i have a property type java.util.List but J2ME don't support list collection).
this is my Jobs entity:
public class Jobs implements java.io.Serializable{
private int id;
private String title;
private CompUsers compusers;
....
private Date publishDate;
private List requerment;
....
// geter and seter
}
my question is: how can i create J2ME client stub with this problem?

Consuming services that consume other services

What is the best way to confirm that these consumed services are actually up and running before I actually try to invoke its operation contracts? I want to do this so that I can gracefully display some message to the customer to give him/her a more pleasant user experience. Thanks.
I created an IsAvailable method that checked all of my underlying dependencies for my service. My client would call this method before doing anything else with my service. If it returned true, my service was available for use.
We also put intermediaten checks to rollback any changes if one of the underlying dependencies was not able at the time of the transaction.
Example:
Here is a simple example of how my IsAvailable is used by the client:
IsAvailable code
[WebMethod]
public bool IsAvailable()
{
bool EverythingUpAndRunning = true;
try
{
string TestConnectionString = WebConfigurationManager.ConnectionStrings["Sql"].ConnectionString;
SqlConnection sqlConnection = new SqlConnection(TestConnectionString);
sqlConnection.Open();
sqlConnection.Close();
sqlConnection.Dispose();
}
catch(Exception ex)
{
EverythingUpAndRunning = false;
}
return EverythingUpAndRunning;
}
The client code:
MyWebService proxy = new MyWebService();
if(proxy.IsAvailable)
{
//if true, you can use the other available methods in the service
}
I wouldn't consider myself a part of the SO Community but I have been in this situation before and it was simple exception handling around the service calls. If you're in control of the services, than you can put up a status method that returns it's current state. If the network is down and you can't even hit the service than you'll have to handle that with some exception handling but you could get a status back if the parent service is unable to use it's child services.
If you're following SO though, my own opinion here, you shouldn't be concerned with the consumed service consuming other services.