• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Can you mock a database?

 
Ranch Hand
Posts: 63
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello!
I'm currently working on a webapp which interracts with a db, quite alot actually.
As it is right now, all my tests make calls to the existing db.
I've heard about test databases which contain test data, how do I create one, and how do I use it in my test cases?

Also, my update and remove use the primary key(an auto-incrementing int called id) to identify which row to update/remove. (Kind of obvious eh..)
Anyway, this means that in my test case I need to send in an int with the remove/update methods,
but since the id is AI the int I send in has to change each time I run the test case.
How can I change that? It's rather tedious to always make sure that there is a row with the id I make the call with.
Will "mocking" the database help with this issue?

Appreciate any help,
Alia
 
author & internet detective
Posts: 41905
909
Eclipse IDE VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Alia,
While you could mock a database, it sounds like you want to use a real database - just a different one. I suggest taking a look at dbUnit. it allows you to always test with the database in the same state. Which eliminates the row being present problem you described.
 
Alia Huss
Ranch Hand
Posts: 63
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
dbUnit, right! I'll check it out, thank you!
 
Alia Huss
Ranch Hand
Posts: 63
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Right so I've downloaded the DBUnit .jar and it's in put snuggly along with the other .jars (JUnit, mysql-connector etc.)
But I'm having a problem with using it. I found a tutorial, which I more or less copied and then made to fit my own tests,
this is it:



Is there anything visibly wrong with it?

When I run the test I get this error message:

java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at org.slf4j.impl.JCLLoggerFactory.getLogger(JCLLoggerFactory.java:69)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:209)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:221)
at org.dbunit.DatabaseTestCase.<clinit>(DatabaseTestCase.java:50)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at junit.framework.TestSuite.createTest(TestSuite.java:54)
at junit.framework.TestSuite.addTestMethod(TestSuite.java:280)
at junit.framework.TestSuite.<init>(TestSuite.java:140)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestLoader.getTest(JUnit3TestLoader.java:102)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestLoader.loadTests(JUnit3TestLoader.java:59)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:445)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
... 17 more

I googled it and on another forum they said that you needed two additional .jars named, slf4j-api-1.5.6.jar and slf4j-jcl-1.5.6.jar, which I also downloaded and added to the buildpath.
Sadly, it still doesn't work. Any ideas on why?

Regards,
Alia
 
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You need the Apache Commons Logging library in the classpath; that's where the "org/apache/commons/logging/LogFactory" class is.
 
Alia Huss
Ranch Hand
Posts: 63
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Right, forgive me for being so green, asking all these silly questions *smiles*
But how do I get it?
Do I download it from http://commons.apache.org/downloads/download_logging.cgi? And if so, should I choose the binary one or the source?
And, how do I add a library to my classpath? I can't remember every doing it, not by myself anyhow.

Thanks again!
 
Ulf Dittmer
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, that's where you get it; you need the binary build. The file is named common-logging-1.1.1.jar or something like that.

You put it together with the other jar files. You mentioned above that you added jar files for MySQL, DBUnit etc. - just do whatever you did with those file with this one as well.
 
Alia Huss
Ranch Hand
Posts: 63
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Right thanks!
And there I got another exception to add to the list.
At


org.dbunit.dataset.DataSetException: java.net.MalformedURLException
at org.dbunit.dataset.xml.FlatXmlProducer.produce(FlatXmlProducer.java:370)
at org.dbunit.dataset.CachedDataSet.<init>(CachedDataSet.java:97)
at org.dbunit.dataset.CachedDataSet.<init>(CachedDataSet.java:81)
at org.dbunit.dataset.xml.FlatXmlDataSet.<init>(FlatXmlDataSet.java:303)
at org.dbunit.dataset.xml.FlatXmlDataSet.<init>(FlatXmlDataSet.java:290)
at com.jayway.konfbooking.test.dbUnit.TestDbUnit.getDataSet(TestDbUnit.java:24)
at org.dbunit.DatabaseTestCase.setUp(DatabaseTestCase.java:150)
at junit.framework.TestCase.runBare(TestCase.java:132)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.net.MalformedURLException
at java.net.URL.<init>(Unknown Source)
at java.net.URL.<init>(Unknown Source)
at java.net.URL.<init>(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at org.dbunit.dataset.xml.FlatXmlProducer.produce(FlatXmlProducer.java:357)
... 19 more

This is getting tiresome *smiles*
I wonder why they don't make tutorials that actually work.
Some info on which libraries were needed would have saved both me and you alot of trouble. Ohwell.
Sod's law and human factor at it's very best. *grins*

So, what does that mean? MalformedURLException?

Thanks for bearing with me!
 
Ulf Dittmer
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Where (in which directory) do you keep the file "input.xml"?
 
Alia Huss
Ranch Hand
Posts: 63
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It's in the same folder/package as the test class.
And a collegue of mine found where the problem was,
he removed the .getClassLoader() from the code-snippet i showed you in my previous reply, and now it works!

Thank you so much for your help!
Finally I can move on and do some real testing.

Regards,
Alia
 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Any time when you see this exception "org.dbunit.dataset.DataSetException: java.net.MalformedURLException" this is an indication that something wrong with the dataset file (input.xml) that we are referring.
There could be many reasons - Name of the file, path of the file, location of the file.

In my case, i had changed the file name from input.xml to source_test.xml and forgot to change the referece to this in the test class. So every thing messed up.
started getting the "org.dbunit.dataset.DataSetException: java.net.MalformedURLException".. after one hour i understood the reason.

Hope this is useful.
 
Ranch Hand
Posts: 50
5
Oracle Postgres Database Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
While I generally agree with the other answers indicating that running such tests against an actual database might be better in the end, database mocking can still be useful in some situations - specifically because you mention not wanting to change the ID in your test case for every test run.

jOOQ is a database abstraction framework that includes a mock database as described in this blog post:
http://blog.jooq.org/2013/02/20/easy-mocking-of-your-database (see also some interesting comments about this approach in a syndicated repost on DZone).

Essentially, the jOOQ mock database is a simple JDBC driver that implements the most important JDBC types (Connection, Statement, ResultSet) and loads mock data from a file like this:



The above mock database can then be used as such:



Note, while the above example shows how to use a jOOQ MockConnection with the jOOQ API, you're not required to do that. You can use jOOQ's MockConnection with any application built on top of JDBC, adding jOOQ only as a test dependency.

More useful information can be found in the relevant Javadocs
reply
    Bookmark Topic Watch Topic
  • New Topic