Persistence of data in each iteration of PactVerify in the provider - java

What is the best way to perform a test of contracts, when the endpoint of the provider performs a persistence of data?
For example, the registration of a client. Should I consider the rollback of the data in the pipeline?

Considering that Client Driven Contract tests are not (usually) supposed to be functional tests, I mock everything bellow my provider Resource that handles the rest call. Therefore, no data is persisted and it also simplifies the test a lot, because you remove any dependencies on external components, including databases.
For instance, if your ClientResource (or ClientController, depending on your name pattern) calls a ClientRepository, the ClientRepository would be mocked.

I make the decision based the the tradeoffs of mocking/not mocking for each particular codebase. I've worked on microservices where it was very easy to just rollback the transaction, so I used the real database for those tests. I've also worked on systems where it made more sense to mock the repository, as suggested by Fabricio. I always mock downstream service dependencies.

Related

Is there some way to rollback redis data after finish java test code?

Is there some way to rollback the data in redis after test code run.
I worked on a java web project using spring boot 2.
I know redis does not provided rollback operation.
So using another redis (like some embedded redis) in test can ensure test code does not change the redis data. And make a mocked redis client to get data in test redis first and if no data then get from the origin Redis.
Does it workable?
And is there a ready made package implements this function?
Or has any simpler way to rollback?
First of all, you should be clear on terms. Either you are doing a real (narrow) unit test, then you absolutely decouple your code under test from any "real" resource, such as databases or file systems or remote servers. In other words: then you mock out such dependencies.
Otherwise, you are doing functional testing. And there are simply too many options to give a meaningful answer here. One example would be Redis Mock.
But as said: the real answer is that you get clear on your requirements. You should do unit-tests that mock out on a lower level, directly at the (single) class under test.

Spring boot REST application testing approach

I have a Spring boot + REST application. When I need to write unit testing, should I directly invoke the service beans or call the rest controller? If I invoke the rest controller directly, I have to use RestTemplate and invoke the rest api as a client, right?
What would be the best and required practice?
If I invoke the service beans directly it will result in less code coverage because controller methods code will be not covered. Is that acceptable?
Hmm, this is a complex question but I'll answer as best I can. A lot of this will depend on you/your organization's risk tolerance and how much time they want to invest in tests. I believe in a lot of testing, but there is such a thing as too much.
A unit test tests the unit of code. Great, but what's a unit? This article is a pretty good discussion: http://martinfowler.com/bliki/UnitTest.html but a unit is basically the smallest testable part of your application.
Much literature (e.g. https://www.amazon.ca/Continuous-Delivery-Reliable-Deployment-Automation/dp/0321601912/ ) describes multiple phases of testing including unit tests which are very low level and mock externalities such as DBs or file systems or remote systems, and "api acceptance tests" (sometimes called integration tests although this is a vague term that can mean other things). This latter type fires up a test instance of your application, invokes APIs and asserts on responses.
The short answer is as follows: for unit tests, focus on the units (probably services or more granular), but the other set of tests you describe, wherein the test behaves like a client and invokes your api, are worthwhile too. My suggestion: do both, but don't call both unit tests.
Best Approach is to Test VIA Controllers. WebServices are entered and values are returned here. So Controller is having quite a good role in this. There can be small logic as well, you may miss that
You can Try Using the MockMvc Method for testing controllers.
Reference: Reference-1, Reference-2
Or use the RestTemplate as you mentioned in question Reference-3
It is based on what you want to test, you can separate your test, specially if you have team of developers, make test case to test your business "services", and another test cases as integration test to use REST template, in this case you can figure your bugs faster and easier.
It depends on what you want to do.
One approach would be to unit test the units of work, like the service and the MVC controller. These test will only test eventual logic found in this classes and try to reach a high branch coverage, if applicable.
Besides this, you can write an integration test that makes the HTTP request, goes to the real service bean and only mock an eventual resource access.
For integration tests you can use Spring's support, see here: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html#spring-mvc-test-framework

GWTTestCase and setting up your persistent data sources

I'm currently unit testing some GWT RPC services with unit tests extending GWTTestCase. All the testcases basically rely on test data being available in the persisted store. I cant set this up from the GWTTestCase since GWT complains about the hibernate objects not being serializable(i suppose the entire class gets compiled into javascript, and not just the actual testcase).
I could obviously just insert it into the database and leave it, but I don't really like that solution.
Currently, I added some methods to the RPC services that basically sets up the service for testing, and one that removes everything. Again, I think this is a bad solution. I would love to be able to use the normal #BeforeClass and #AfterClass annotations I use when unittesting the domain model. Can anybody share their experiences with GWTTestCase GWT RPC implementations and how you populate you persistent store with data before the testcases gets run.
-Daniel
What forces you to use GWTTestCase to test RPC services ? Can't you just directly invoke the RPC methods on the RPC implementation class ? You only need to mock the HTTPRequest object. So you can just use plain JUnit tests instead of the slow to start GWTTestCase.

What does a mocking framework do for me?

I have heard some people who I cannot talk to are big fans of jmock. I've done test centered development for years and so I went through the website and looked at some of the docs and still can't figure out what good it is.
I had the same problem with spring. Their docs do a great job explaining it if you already understand what it is, so I'm not assuming that jmock is of no value. I just don't understand what it does for me.
So if jmock provides me with the ability to mock out stubbed data, let's go with an example of how I do things and see how jmock would be better.
Let's say I have my UI layer that says, create me a widget and the widget service, when creating a widget, initializes the widget and stores pieces of it in the three tables necessary to make up a widget.
When I write my tests, here's how I go about it.
First, I re-point hibernate to my test hypersonic database so I don't have to do a bunch of database set up. Hibernate creates my tables for me.
All of my tests for my classes have static factory methods that construct a test instance of the class for me. Each of my DAOs create test versions that point to the test schema. Then my service class has one that constructs itself with DAOs generated by the test class.
Now, when I run my test of the UI controller that calls the service, I am testing my code all the way through the application. Granted that this is not the total isolation generally wanted when doing a unit test, but it provides me, in my opinion, a better unit test because it executes the real code all the way through all of the supporting layers.
Because Hypersonic under hibernate is slow, it takes slightly longer to run all of my tests, but my entire build still runs in less than five minutes on an older computer for full build and packaging, so I find that pretty acceptable.
How would I do things differently with jmock?
In your example, there are two interfaces where one would use a mocking framework to do proper unit tests:
The interface between the UI layer and the widget service - replacing the widget service with a mock would allow you to test the UI layer in isolation, with the service returning manually created data and the mock verifying that the expected service calls (and no others) happen.
The interface between the widget service and the DAO - by replacing the DAO with a mock, any service methods that contain complex logic can be tested in isolation.
Granted that this is not the total isolation generally wanted when doing a unit test, but it provides me, in my opinion, a better unit test because it executes the real code all the way through all of the supporting layers.
This seems to be the core of your question. The answer has a number of facets:
If you're not testing components in isolation, you do not have unit tests, you have integration tests. As you observe, these are quite valuable, but they have their drawbacks
Since they test more things at the same time, they tend to break more often, they tend to break in large groups (when there's a problem with common functionality) and when they do, it is harder to find out where the actual problem lies
They are more constrained in what kinds of scenarios you can test. It can be hard or impossible to simulate certain edge cases in an integration test.
Sometimes a full integration test cannot be automated because some component is not sufficiently under your control (e.g. a third-party webservice) to set up the test data you need. In such a case you might even end up using a mocking framework in what is otherwise a high-level integration test.
I haven't looked at JMock in particular (I use Mockito) but in general mock frameworks allow you to "mock" external services such that you only need to test a single class at a time. Any dependencies of that class can be mocked, meaning the real method calls are not made, and instead stubs are called that return or throw constants. This is a good thing, because external calls can be slow, inconsistent, or unreliable--all bad things for unit testing.
To give a single example of how this works, imagine you have a service class that has a dependency on a web service client. If you test with the real web service client, it might be down, the connection might be slow, or the data behind the web service might change over time. How are you going to write a reliable test against that? (You can't). So you use a mock framework to mock/stub the web service client, and you create fake responses, fake errors, fake exceptions, to mimic the web service behavior. The difference is the result is always fast and consistent.
Also, you'd like to test all the failure cases that a given dependency might have, but without mocking that's hard to do. Consider the example I gave above. You'd like to be sure your code does the right thing if the web service throws an IOException because the web service is down (or times out), but it's not so easy to force that condition. With mocking this becomes trivial.

Test Cases: Mocking Database using Spring beans

Our application has a service layer and a DAO layer, written as Spring beans.
While testing the Service Layer- I do not want to depend upon a real database so I am mocking that by creating a 'Mock' Impl for the DAO layer
So when I am testing the Service layer- I chain the Service layer beans to the Mock DAO beans
And in Production- will chain the Service layer to the 'real' DAO beans
Is that a good idea ?
Any alternate suggestion on how to mock the database layer ?
Clarification:This question is about testing the Service Layer and not the DAO layer.
While testing the service layer- I assume that either the DAO layer has already been tested or doesn't need testing.
The main thing is- how do we test service layer- without being dependent upon the DAO implementation- hence I am mocking the DAO layer
This is a technique we've been using for many years now. Note that when it comes to mocking the DAO interfaces you have some choices:
Create mock instances as real Java classes
Use a dynamic mocking framework such as jMock (my preference) or EasyMock
Dynamic mocking frameworks allow you to stub out a variety of circumstances (no data, 1 row, many rows, exception throwing) without having to create complex classes to stub out the behavior you wish to test
That's a great way to use mocking to test the database. I don't think any alternative suggestion is necessary; I think you've got the right technique already!
You are definitely on the right track.
My mocking framework of choice is Mockito
As I understand the question it is explicitly dedicated to best practices regarding testing DAO layers, as mocking a database seems nnot so straightforward as mocking the DAO layer when testing services.
Personally I'd raise the question back if it's reasonable to really unit test a DAO layer in the classical unit testing meaning. If you design your DAO layer properly it does not do much more than mapping domain objects to queries.
That said I alway propose to use an embedded database like H2, HSQL or the Java 6 embedded Derby to do things like this as mocking a datasource is really much more effort than simply raising an embedded database. Spring 3 will provide a nice builder pattern to create such databases on the fly. RC1 of it will also introduce a jdbc namespace to ease setup further. See this one for details.
But even with current Spring 2.5 branch using an embedded database is just a matter of taking the databases JAR and setting up a DataSource accordingly.

Categories

Resources