How to test a microservice by mocking the dependencies? - unit-testing

I've a RESTFul microservice written in Grails. This microservice has it's own DB. It also depends on two other microservices.
A typical workflow of the service is:
Receives a GET request from a client e.g. browser
Calls another microservice throw http to get some information
Queries it's own DB to get some data
Send a response to the client
I want to write automated tests for this service. Whenever I'll run the test, it'll do the following:
Mock the external microservices
Create a database and populate it with test data
Run the application and configure it to use the mock services and DB
Run the test cases by sending http requests and matching responses
Here are my questions:
What type of test is this?
What are some good frameworks or tools to write this type of test?
I've a very little knowledge on testing so may be I'm asking stupid questions.

My first suggestion is that your service not know about HTTP requests. It should be a provider to a higher level layer like https://jersey.java.net that can make requests and map the POJO's your service class returns into JSON or whatever to return in HTTP responses.
Your method for #4, "Send a response to the client" should use those external dependencies to gather information and then make a decision.
Some cases to cover:
If the other micro service can return A, B, or C and the DB can return D, E, or F, then you have 9 scenarios to test. Use mocks to provide all those varieties of data and then make assertions about the result. If there are many more possibilities, then consider adding extra methods for information-gathetering and testing them on their own.

Related

How to write unit tests for gremlin queries in Java?

for example connecting to client:
val client = Cluster.open(MapConfiguration(config)).connect()
and executing the query
client.submitAsync(PreparedStatement.addUser, map).await().all().join()
PreparedStatement.addUser - gremlin string
The question is: how to unit test client queries in Java. I thought of unit testing our queries with inMemoryDB. Can we run inMemoryDB as a client, because by default return traversal() if connecting to memory DB? Or can we execute a gremlin query string on traversal?
If you are sending Gremlin strings to Gremlin Server, you could treat your tests as integration tests and actually start a Gremlin Server instance with a JanusGraph in-memory instance configured perhaps. In some cases, a TinkerGraph might suffice as well depending on what you need to test.
If you wanted more pure unit tests you would have to do some mocking, but that will be complicated as there are some non-public classes involved and the class dependencies are non-trivial. I think the first problem would be with the ResultSet and ResultQueue classes that the Client needs. I created this issue TINKERPOP-2428.
I think that bytecode based requests are less challenging that scripts as you can mock the RemoteConnection to return your own Traversal instance. There is even an EmbeddedRemoteConnection that would let you define a local GraphTraversalSource to test against (if that situation suited you).

What should unit test cover in a list display app from api?

I have an app that connects to an API endpoint and displays a list of people. I want to write a unit test for the app. But I am not sure what to test here. There is no arithmetic operation happening It's just fetching the data from API and displaying it.
What should the unit test cover in such a scenario?
If a test can never fail, then it's not really testing anything. In your case though, a network api call is being made. And network calls can fail all the time. Depending on how you are making your network call you can either:
create a fake web server that can return a variety of error codes
create a mock api service that can return a variety of error codes
don't test anything
There are all kinds of tests you can use, behavioural, unit, functional, integration, black box, user acceptance testing.
What does testing do for you? Does it document code behaviour? Does it lock in the behavior of a function? Does it ensure that something works?
Depending on your needs, you may not need a test. Or, you may need a lot more. It's up to you.
Unit tests are designed to ensure that a behavior or set of behaviors occur(s) when you invoke a unit of code.
In this case, you have code that is fetching the data from an API and returning it. You might want to test the following:
Your code makes a network call to the API.
When the API returns a successful response, your app renders the data.
When the API returns a failed response, you gracefully handle the failure.
Of course these steps will probably vary depending on your use case. You can look into stubbing the API to understand how you can simulate API invocation failures.

send data from server with java ee 6 to client

Problem
We have a client-server application, server side is Glassfish 3.1.2. This app has many users, as well as many modules (e.g. View Transactions, View Banks etc). There are some long running processes invoked by client which run on server. Currently we have not found a nice solution to show the user what is going on on the server side. We want the users to get updated messages from server with given frequency. What would you suggest to use?
What we have done/tried
We (independently) used an approach with Singleton bean and a Map of client IDs similar to this, and it works of course. But then on the server side every method doSomething(Object... vars) must be converted to doSomething(Object... vars, String clientID) or whatever ID is type of. The client pulls data from server say once per second. I would like to avoid adding facades between server and client.
I was thinking about JAX-WS or JAX-RS, but I'm not familiar with these technologies deeply and not sure about what they can do.
Sockets
I should note that on the server side we have only Stateless beans (there is a reason for that), that is why I did not mention the use of Stateful bean (which is very good candidate I think).
Regards, Oleg
WebSocket could be a suitable choice, it allows the server to send unsolicited data to clients with no strong coupling, you just have to store a client id to map client connections to running tasks and be able to push updates to the right connection.
The client id/socket connection mapping can be maintained in a singleton bean using an in-memory structure, i.e. a hash map, or a permanent datastore for scalability purposes or in case you need a robust solution.
Some useful links to better understand WebSocket technology are this and this.

Automated test of client/server application

As the headline says, how would you test a client/server application, that is written in C/C++, that talks through a protocol over a network? Im a bit confused on how to do this. I have thought about making some mocking, but I have never tried mocking, so I dont know if this is the best way.
How should I do this? I have written many unit tests, but never tried to test something that interact over a network.
I use the command pattern in the unit test driver (client) to send test commands to the server. The advantage of this is that the test is coded in one place.
Example for testing a request timeout:
Client sends a sleep command to server and then the request. The request times out and the test case is passed.
Typically you'll want to use mocking to verify that each side reacts as required to messages from the other side (e.g., that when the client receives a response from the server that it processes that response correctly).
To test the network functionality itself, you can test both running on the same machine, and you can run one (or both) inside a virtual machine. If you have two network adapters, you can even dedicate each to a virtual machine so the network traffic actually goes out one, to a switch/router, and comes back in the other (particularly useful when/if you want to capture and verify packets).
I have some client/server code that I unit test through the loopback address. I use some mocks when I have to test error conditions. So, I test with the real code when I can and the mocks when I need to trigger very specific conditions.

Communication between client class library and web service / web service and server class library

Wondering what others do / best practice for communicating between layers. This question relates to communication between layers 2-3 and 3-4.
Our Basic Architecture (in order) as follows:
UI
Front End Business Classes
Web Services
Back End Business Classes
DAL
The web services are just a façade that include logging and authentication to back end class libraries.
As such, the web service is passed a request object that includes the parameters required by the web method along with the user credential (the user credential for example is stored in a base class as we will always need to pass this to the webservice) and responds with response objects (has things such as status and message, if failed etc along with the object required) both request & response use a custom generic class/or interface where only one result is returned, otherwise a class needs to be created.
Sometimes it makes sense to do this for the response object at layer 4 (though we don't use a request object unless a lot of parameters need to be pasaws), in which case we just have an adapter class in layer 3 which returns this to the client. For consistency I have considered doing this all the time, though think it may be overkill.
So to iterate the question, what are the best practices for communicating between layers? and should/do people use this method outlined above (it works well for us) and should layers 3-4 implement similar method to 2-3?
Possible considerations:
currently everything is coded in house by a team of developers, some client code may be outsourced in the future
future web services will be WCF based (not sure if that effects design other than coding to interfaces which I would prefer anyway).
We use .net
For the sake of completeness:
It seems a good idea to have the response / requests in the class library, that way if you want to change the web service to WCF, there is less work to do.