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.
Related
I have a java/jersey api that is called from the front end. I need to write tests for the java code. How the code is written is:
1. The api call executes the resource method, this calls a separate method that gets data from db and returns to the resource method. This then returns a javax.ws.rs.core.Response to the client.
This is going to be my first time writing tests, so please answer considering I know nothing. What is the best way to start here? And what types of tests should I write. Unit tests are what I’m aiming for here.
Now I have done a lot of research here and I’m leaning towards using JUnit + Mockito to do this. But how do I check for the data in a Response object?
And how should I check the other file that is getting data from db? I found out DBUnit that can do that, but do I need it?
Another framework I came across was Rest Assured. Do I need to include that also? Or can the same things be done with JUnit/Mockito?
I just want some direction from people who have tested out jersey api’s. And want to know what is the most common way to do this.
I do not think there is a best way to do this, what you need to test is often subjective and dependent on the context.
However, you can structure your code in a way that the most important is tested easily and what's left (integration) can be done later / with different tools.
What I suggest here is to follow the principles of the hexagonal architecture. The idea is to keep at the center of your application and without any kind of dependencies (imports ...) to any framework (jaxrs, jpa, etc.) all business rules. These rules can be easily designed with TDD. You will then have very short running tests. It may be necessary to use Mockito to mock implementations of SPI interfaces.
In a second time, you can use this "core" by wiring adapters to the outer world (HTTP, databases, AMQP, etc.), using API and implementing SPI interfaces.
If you want to test these adapters, you exit the scope of unit-tests, and write integration-tests. Integration with a framework, a protocol, anything really.
This kind of tests can use a wide variety of tools, from a framework-related mock (like Jersey test framework), in-memory database (like H2), to fully operational middleware instance using tools like testcontainers.
What is important to remember when writing integration-tests is they are slow in regards of unit-tests. In order to keep a feedback-loop as short as possible, you will want to limit the number of integration-tests to a minimum.
Hoping this will help you!
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.
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.
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.
I am working on a legacy code where there are several methods with calls to Stored procedures from the service layer itself as opposed to hibernate. Is it possible to test those methods in any manner so that my code coverage can increase ? I am using java 1.5 and sql server 2005.
This sounds like a classic requirement for mocking. You would mock out the database connection and communication (via, perhaps, dependency injection) by supplying a mocked version of the objects that return static and consistent test data. As such you don't have to rely on the database connection (making your tests faster and more reliable).
Such frameworks exist for Java - check out JMock or EasyMock, for example.