In my testing code I need to have a blank/empty database at each method. Is there code that would achieve that, to call in the #Before of the test?
Actually you always can use JPQL,
em
.createQuery("DELETE FROM MyEntity m")
.executeUpdate()
;
But note, there is no grants that entity cache would be cleaned also. But for unit-test purposes it is look like good solution.
In my testing code I need to have a blank/empty database at each method.
I would run the test methods insider a transaction (and rollback at the end of each method). That's the usual approach. I don't see the point of committing a transaction and writing data to the database if you DELETE them just after. Just don't commit.
An alternative (not exclusive) would be to use DbUnit to put your database in a known state before a test execution. When doing this, you usually don't need to clean it up.
Another option would be to use raw JDBC to drop the database if exists and then have JPA recreate the whole database. Will be pretty slow though.
Related
I am brand new to Liquibase...
Today I wrote a Liquibase changeset using --liquibase formatted sql.
I created two tables where the second had a foreign key dependency on the first.
My rollback strategy was (mistakenly) drop table1; drop table2. When I ran the update and tested the rollback it failed because of the foreign key constraint. However, when I corrected my mistake and attempted to rerun it, it failed because the checksum didn't match.
I know that the obvious answer is to make more atomic changesets, however...
Does Liquibase support a way to test this sort of thing without actually running it so I can avoid the problem with the checksum on the edited rollback?
Failing that: is there a workaround for the checksum problem that will let me edit my files after running the update? (ctrl+z?)
The short answer to your question is, no Liquibase doesn't have such a thing.
Liquibase is a great toolkit, but it doesn't have a lot of bells and whistles, and it doesn't have much of an 'opinion' on how it should be used, or what your workflow should be. In your case, I would suggest that one way to deal with the problem is to just drop the database and then re-create it from the changelog. If you have already deployed the changelog in multiple places, that might not be possible, and if you weren't prepared to do that, that could be a problem.
There is an option to specify a validChecksums attribute on a changeset, so you could use that, but in general if you are using that you are making your changelog more complicated.
If you wanted to look at something that is more full-featured and that has the ability to forecast changes before they are deployed, please check out my company's product, Datical DB. It uses liquibase at its core, but adds a whole lot more (and is priced accordingly).
Liquibase provides updateTestingRollback command that basically updates the database, then tests its rollback and if successful, applies the changes again.
Your problem with invalid checksums may be solved with clearCheckSums command. It removes current checksums from database and on next update change sets that have already been deployed will have their checksums recomputed, and change sets that have not been deployed will be deployed.
For more details check Liquibase commands.
I want to have single FakeApplication for all my test.
My final goal is to set up database and use it in all test. They should access single database and share data in it. I can not use H2, because I use some MySQL features(fulltest search, for example). But if there is no started application, I can't call "DB.withTransaction" because there is started application yet. But it should start once, because it drops all tables and create new ones.
How can I do it?
I am using scala and JUnit. I solved my problem next way: I just created singleton for my fake application, which is retrieved as an implicit val. So, all work about creating and cleaning database is done on first fetch.
When I Add-Migration, I get the appropriate DbMigration class with the Up / Down methods, where I am able to make schema changes and (with the use of the Sql() method) can make data/content changes as well.
I'd like to be able to make content changes per migration using the database context. I understand that I could use the Seed method in a Configuration class, but my understanding is that I can only wire up one Configuration with my initializer.
I'd prefer to have a UpCompleted()/DownCompleted() methods that would provide access to the db context after the migration completed. This would enable writing incremental data/context change "scripts" in a manner that would be less prone to errors than using the Sql() method.
Am I missing something? Is this possible?
Thanks!
That doesn't really work because the context only has your most recent model - which can only be used to access the database once the most recent migration has run (which is effectively what Seed achieves).
For an example of how this idea breaks, if you moved a property from one class to another then seed logic from older migrations would no longer compile. But you couldn't change it to use the new property because the corresponding column wouldn't exist in the database yet.
If you want to write this kind of seed/data-manipulation logic, you need to put it at the end of the Up/Down methods and use the Sql method to perform it using raw SQL.
~Rowan
In NHibernate, I have show_sql turned on for running unit tests. Each of my unit tests clears the database and refills it, and this results in lots of sql queries that I don't want NHibernate to output.
Is it possible to control show_sql without destroying the SessionFactory? If possible, I'd like to turn it off when running setup for a test, then turn it on again when the body of the test starts to run.
Is this possible?
The only place you can set this is when building a NHibernate.Cfg.Configuration.
Once you've created a SessionFactory from your Configuration, there's no way to access the configuration settings, which I think is one of the reasons for using a factory pattern: to ensure that instances once successfully built can't be messed up by runtime re- or mis-configuration.
If you really need that feature, get the NH source code and find the place where the show_sql setting is evaluated.
Another option although it may/may not be as good is to use NHProf and just initialise NHProf when testing.
NHProf doesn't log setting/clearing database just queries used.
I'm looking into adding some unit tests for some classes in my data access layer and I'm looking at an update routine that has no return value. It simply updates a row based on the id you provide at whichever column name you provide.
Inside of this method, we collect the parameters and pass them to a helper routine which calls the stored procedure to update the table.
Is there a recommended approach for how to do unit testing in such a scenario? I'm having a hard time thinking of a test that wouldn't depend on other methods.
Test the method that reads the data from the database, first.
Then you can call the update function, and use the function that was tested above, to verify that the value that was updated is correct.
I tend to use other methods in my unit tests as long as I have tests that also test those that were called.
If your helper functions are in the database (stored procedures or functions) then just test those with a DatabaseUnitTest first, then test the visual basic code.
I would just use a lookup method to validate that the data was properly updated.
Yes, technically this would relay on the lookup method working properly, but I don't think you necessarily have to avoid that dependency. Just make sure the lookup method is tested as well.
I would use the method to get that data and check the return value to what you updated and Assert the expected value. This does assume the method used to retrieve the data has been tested and works correctly.
I use nhibernate and transactions and for unittests I don't commit to the database but I flush the session which gives the same errors if needed but doesn't write the data.
Of course if you have a build server you just run the unittests against a freshly made database which is freshly made on each build. Try using an filebased database like firebird or something.