I am working on a Java web app with unit/integration tests. App gets deployed to Jetty and uses H2 db while running the integration test phase of maven. I've one oracle function which is called from dao layer which can not be migrated to H2 db, hence i want to mock/skip this part in code while running the test cases.
I thought of having a flag which can tell if i'm running application in test mode and put the condition in code for it, but doesn't look like cleaner approach to me. Please suggest best approach to achieve this.
Extract the Oracle native call into a separate class (probably some DAO). Inject that DAO to class that uses it. Create a second implementation of that DAO, doing nothing in place of calling Oracle. During integration testing inject the latter implementation.
Avoid flags in your code. If you are using Spring, use build profiles that will selectively create one implementation or the other.
That's how dependency injection helps you test your code: if you want to mock some part of the system, just inject mocked version.
Please use some good Mocking frameworks such as mockito or jMock or some other similar mock frameworks.
Please Note: You might be required to re-factor your code to make it more testable.
If the question truly is:
How do I skip a section of code when unittesting in java
then I agree with the answers given. Dependency injection, mocking frameworks are absolutely the right way to go to do true unit testing.
However if the question is:
How do I skip a section of code when using JUnit (or other unit testing framework)
Then I think the answer is "it depends". Sometimes I use JUnit for integration testing - snippets of client code that I run against a test server to save me the trouble of doing these client side tests manually via a GUI. In this case I use system properties for example in my base class I have:
protected boolean skipTest()
{
String port = System.getProperty("jersey.test.port");
// don't run this test unless developer has explicitly set the testing properties
// this is an integration test, not a unit test
return port == null;
}
Then in the actual test class it looks like this:
// verify a successful login
#Test
public void testLogin()
{
if (skipTest())
return;
// do real test
So, my thought is if you really cannot refactor the Oracle stuff out of your DAO, then you really are doing an integration test and it's OK to have a skipTest in your unit test.
Related
I am a Java developer. We want to use cucumber testing in our project. We are working mainly on creating APIs. I am good with unit testing and researching about cucumber.
I am thinking about testing persistence methods - CRUD operations as an starter. My questions is that what could be the scenerios in this testing.
Also should I mock the database by creating tables in the feature file. Should I use mockito with Cucumber to mock call to some other services which connects to database and server.
What should be the cucumber testing in these scenerios and whats the best way to create framework to use cucumber in our Java API's project.
Also, how to populate models if not using database
IMO Gherkin (the language you write Cucumber features in), is good for writing business readable, simple scenarios.
To answer quickly, I would say that Cucumber is not a good fit for testing methods, if it is what you want to do.
As you can see with the file naming convention, you write *.feature files, and I think these files must only contains feature-related descriptions.
However, if you do have features to test, you have to choose how to test them
disconnected, can be run quicky by your CI
you will have to mock everything that cannot start-up in the build lifecycle
and they are solutions to start almost anything using Docker, like Testcontainers
connected to a environment
you do not have to mock anything
your tests may be slower
your tests may break because of the environement (failed deployement, server down, etc.)
I am writing integration tests for a Java EE Servlet using Arquillian + JUnit. I need to be able to execute code before the server launches.
So is it possible to execute code before #Deployment? I tried #BeforeClass with no luck.
The reason I need to do this, is because trust and keystores for ssl needs to exists before the server starts. I am creating the stores problematically and is saving them to files afterwards.
I know a possible workaround would be to have static trust and keystores, but I prefer to create them programmatically before the test starts for full flexibility when writing tests.
There is not really a need to have your own specialization of Arquillian JUnit runner. This solution would be only for JUnit 4.x in that case which you are using for writing your tests.
Arquillian let you hook through extensions mechanism to its runtime and this way you can have some custom logic executed before server startup to provide your keystores. I believe this is more elegant and portable solution.
Please have a look at sample extensions on Github (especially lifecycle would be a good starting point). If you feel like implementing it this way I'm more than happy to help you. The event you might want to observe on is either BeforeSetup or BeforeStart.
You have two other options for executing code before and after your test:
Rules or ClassRules are executed around and before/after
Using a custom Testrunner (extending the default 'Arquillian' runner)
But as the static deployment method is not invoked by a rule, I assume you have to go for the testrunner.
Im trying to understand how all things are related with Spring. However I do not understand why mockito is used when unit testing spring code? Can not spring handle to same DI that mockito does? What is it that mockito contributes that is not possible to do with pure spring?
Clarification:
My thinking goes that I can just use a different application context for testing where I create the stub beans I need as dummy objects.
Spring is not a mocking framework. It's a dependency injection framework.
You use Mockito because it allows mocking collaborators of the class under test. So, if you're testing a service, and this service uses a repository that gets and stores data in a database, you mock the repository so that your test is a real, isolated unit test that doesn't need an Oracle database to run.
Read https://stackoverflow.com/a/28783849/571407 for a more detailed introduction to mocking.
You don't need Mockito to test Spring applications. You can start your server and use the injected dependency directly. But sometimes it is easier to mock one (or more) dependency(ies), for example a select of your database, because you want to test the code that you have written and not the select of the database, which also includes that you need a database with some testdata (or at least mocked testdata). In fact you use Mockito to keep dependencies of your tests out, so you can test the code that your application uses and to "ignore" dependencies of third party test environments.
I got a problem that consumes a lot of time during the development i have to test somes HQL that i put in DAO, but i had to recompile all the project in eclipse and put in tomcat that takes something like 40-60seconds just to start again and if something goes wrong... again had to redeploy...
So, there is a way to test a HQL without recompile everything? like i tried the hibernate tools plugin but i don't see how to do it with annotations (the project is all with annotations, don't make use of hbm files...)
Thanks
Set a breakpoint where you need, debug in 'Display' window and write your any HQL queries in runtime.
http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Freference%2Fviews%2Fdisplay%2Fref-display_view.htm
Maybe helps.
Assuming you are accessing your DAO through a service I would do something like this:
public static void main(String[] args) {
AbstractApplicationContext factory = new ClassPathXmlApplicationContext("application-context.xml");
YourService yourservice = (YourService)factory.getBean("YourService");
YourObject obj = new YourObject("data1", "data2");
yourservice.save(obj);
YourObject foundobj = yourservice.load(1); // or yourservice.findObjectByLabel("label")
System.out.print(foundobj);
}
Or write a junit test. http://www.springbyexample.org/examples/simple-spring-transactional-junit4-test-code-example.html
I would go for the debug option as mentioned by Vaelyr for a punctual need.
If you require stronger assertions I would rather write some tests for the DAO as tshenolo proposed.
But if you have some time and want a nice toy to play with I would create a console page that let you interact with your application.
For that I'll use a groovy (or another script language) interpreter. If you provide the DAO or any other relevant objects to your interpreter context, then you'll have a console to perform all kind of experimentation without to re-compile anything.
You'll be able to run arbitrary code within your app !
For an example with groovy you can have a look here: Embedding Groovy and more precisely here: Embedding a Groovy Console in a Java Server Application
If you don't want to use groovy, you can also have fun with beanshell (pure java) or a rhino (javascript) or any other script language supported by the JVM.
Beware that having this kind of console is a backdoor to your app and that you should not release it as a part of your application.
What I've done in the past to test HQL is write a limited set of integration tests using an in memory db like Hypersonic and the Spring JUnit test extensions. This post describes how this can be done using dbunit. You can also just brute force the data using batch JDBC operations in your setup and tear down.
Cautionary notes: I would not add these test to your suite of unit tests as the data setup and tear down can take more time than a typical unit test. These are really integration tests used to add you in development and debugging of your HQL only. I wouldn't bother testing CRUD operations using these types of tests as then you're just integration testing your ORM framework which should have already been done.
I am trying to figure out the best way(s) to test Service and DAO layers. So, a few sub questions...
When testing a service layer, is it best to test against a mock DAO layer or a "live" DAO layer pointed at a testing environment?
How should SQL in the DAO layer be tested when the only test database is in a shared environment (Oracle/DB2)
How do you solve the paradox of any DAO writes/updates need to be tested with DAO reads which is something that also has to be tested?
I am looking for any good documentation, articles, or references in this area along with any tools to help automate the process. I already know about JUint for unit testing and Hudson for CI.
Get Growing Object-Oriented Software, Guided by Tests. It has some great tips about how to test database access.
Personally, I usually break the DAO tests in 2, a unit test with a mocked database to test functionality on the DAO, and an integration test, to test the queries against the DB. If your DAO only has database access code, you won't need a unit test.
One of the suggestions from the book that I took, is that the (integration) test has to commit the changes to the DB. I've learn to do this, after using hibernate and figuring out that the test was marked for rollback and the DB never got the insert statement. If you use triggers or any kind of validation (even FKs) I think this is a must.
Another thing, stay away from dbunit, it's a great framwork to start working, but it becomes hellish when a project becomes something more than tiny. My preference here, is to have a set of Test Data Builder classes to create the data, and insert it in the setup of the test or in the test itself.
And check dbmigrate, it's not for testing, but it will help you to manage scripts to upgrade and downgrade your DB schema.
In the scenario where the DB server is shared, I've creates one schema/user per environment. Since each developer has his own "local" environment, he also owns one schema.
Here are my answers :
Use mock DAOs to test your services. Much easier, mush faster. Use EasyMock or Mockito or any other mock framework to test the service layer.
Give each developer its own database schema to execute his tests. Such schemas are typically empty : the unit tests populate the database with a small test data set before running a test, and empties it once the test is completed. Use DBUnit for this.
If the reads work against a well-defined, static, test data set (which you should unit-test), then you can rely on them to unit-test the writes. But you can also use ad-hoc queries or even DBUnit to test that the writes work as expected. The fact that the tests are not necessarily run in this order doesn't matter. If everything passes, then everything is OK.