4

I am running some unit test that persist documents into the MongoDb database. For this unit test to succeed the MongoDb server must be started. I perform this by using Process.Start("mongod.exe").

It works but sometimes it takes time to start and before it even starts the unit test tries to run and FAILS. Unit test fails and complains that the mongodb server is not running.

What to do in such situation?

Tilo
  • 33,354
  • 5
  • 79
  • 106
azamsharp
  • 19,710
  • 36
  • 144
  • 222

4 Answers4

4

If you use external resource(DB, web server, FTP, Backup device, server cluster) in test then it rather integration test then unit test. It is not convenient and not practical to start that all external resources in test. Just ensure that your test will be running in predictable environment. There are several ways to do it:

  1. Run test suite from script (BAT, nant, WSC), which starts MongoDB before running test.
  2. Start MongoDB on server and never shut down it.

Do not add any loops with delays in your tests to wait while external resource is started - it makes tests slow, erratic and very complex.

Yauheni Sivukha
  • 2,586
  • 20
  • 22
1

Can't you run a quick test query in a loop with a delay after launching and verify the DB is up before continuing?

Peter Tillemans
  • 34,983
  • 11
  • 83
  • 114
  • You mean to run the test query before running every single unit test? – azamsharp May 29 '10 at 00:10
  • no, after you restart the database so you know it is running before the unittests start. I mean to include it in the same routine which starts the database. – Peter Tillemans May 29 '10 at 00:28
  • I don't understand what you mean by start the database! I don't have any database. It is a MongoDb database which needs a server to be started. I can put a delay after starting the server but it just looks weird! – azamsharp Jun 01 '10 at 15:08
  • If you start the database with a script, you could have a small loop which does a query and retries after a delay if the query fails. Then you know the database is ready for the tests and you can minimise the dead time. – Peter Tillemans Jun 01 '10 at 16:07
1

I guess I'd (and by that I mean, this is what I've done, but there's every chance someone has a better idea) write some kind of MongoTestHelper that can do a number of things during the various stages of your tests.

Before the test run, it checks that a test mongod instance is running and, if not, boots one up on your favourite test-mongo port. I find it's not actually that costly to just try and boot up a new mongod instance and let it fail as that port is already in use. However, this very different on windows, so you might want to check that the port is open or something.

Before each individual test, you can remove all the items from all the tested collections, if this is the kind of thing you need. In fact, I just drop all the DBs, as the lovely mongodb will recreate them for you:

for (String name : mongo.getDatabaseNames()) {  
  mongo.dropDatabase(name);
}

After the tests have run you could always shut it down if you've chosen to boot up on a random port, but that seems a bit silly. Life's too short.

Ben Smith
  • 1,554
  • 1
  • 15
  • 26
  • Yeah I am already doing all of that! Anyway, one thing to be careful when dropping the database or the collections is that every index created on the collection will be lost. I usually go through all the collections and delete individual records instead of dropping the collections or the databases. – azamsharp Jun 08 '10 at 17:25
0

The TDD purists would say that if you start the external resource, then it's not a unit test. Instead, mock out the database interface, and test your classes against that. In practice this would mean changing your code to be mockable, which is arguably a good thing.

OTOH, to write integration or acceptance test, you should use an in-memory transient database with just your test data in it, as others have mentioned.

Ron Romero
  • 9,211
  • 8
  • 43
  • 64
  • I'd say that you mean "the unit test purists" rather than TDD. I find the TDD angle more pragmatic, and if you need to be sure that your code works with MongoDB then you need to test your queries against MongoDB – sMoZely Nov 29 '11 at 19:41