Unit tests and database
NickName:bryanjonker Ask DateTime:2010-06-26T21:47:48

Unit tests and database

This question about unit tests sparked another thing that's been bothering me. I've gone back and forth on three ways to do unit tests when hitting a database.

  1. Create mock objects and plug them in. This has the advantage of not needing a database, but it's time consuming and I'm not sure how much return on investment I'm getting. I've been getting into IOC and moq a little bit, but it still seems painful.
  2. Create a setup and teardown database scripts to create known cases, and test for those. Again, can be time intensive, but still easier to create than mock objects most of the time. And other people at work can still run it assuming they have SQL server on their localhost.
  3. Manually check the dev database and modify unit tests. Intensively manual work, but if I have a "test set" that doesn't change, it seems to work OK. On my machine, at least :-).

I know option 1 is the "proper" way to do unit tests, but of the three, that's probably the option I've used the least (although the latest projects have been with IOC, so that door is open to me). I realize a lot of it depends on what exactly is being mocked and what is being tested, but what am I missing here?

If context helps, I'm in a C# shop, writing in-house applications, only a few developers.

Copyright Notice:Content Author:「bryanjonker」,Reproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/3124071/unit-tests-and-database

Answers
Stephen Cleary 2010-06-26T14:04:02

The first one shouldn't be that hard if you've got a Data Access Layer that exposes just a handful of IQueryable<T> methods. There's a nice trick you can use for fake data: just store the entity objects in a List<T> and use AsQueryable. I find this easier than moq for the data parts.\n\nRegarding IOC, I take the position that it's currently overused (be aware that my opinion represents the minority of programmers in this regard). You can use a tool like Moles during testing to mock without having to abuse your program's design. I don't use IOC unless the design actually calls for it.",


jyoungdev 2010-06-26T14:29:25

I would definitely continue to use true unit tests (option 1). I like Stephen's advice for this.\n\nYou may also find integration tests with an actual database (option 2) necessary to use as well (option 2). Why? Because part of what you need to test (O/R mapping, compatability with the actual DB schema, etc.) are not covered by true unit tests.\n\nAs for setup and teardown logic, inheriting from this usually suffices (using .NET, NUnit, and SqlServer for the database):\n\nusing System.Transactions;\nusing NUnit.Framework;\nnamespace Crown.Util.TestUtil\n{\n [TestFixture]\n public class PersistenceTestFixture\n {\n public TransactionScope TxScope { get; private set; }\n\n [SetUp]\n public void SetUp()\n {\n TxScope = new TransactionScope();\n }\n\n [TearDown]\n public void TearDown()\n {\n if (TxScope != null)\n {\n TxScope.Dispose();\n TxScope = null;\n }\n }\n }\n}\n\n\nEasy as pie.",


drekka 2010-06-26T14:25:50

There's a whole suite of answer to this. The first thing to do is to clearly articulate what you are testing. Is it the facade of an API that has a database behind it, DAO objects, your database structure? \n\nGetting to this will also help you decide the best way to test things. There is also from what I can see an alternative to the ones you list. That is to start up in in memory database such as hsql and run your classes and tests against that. This means that you can create the database structure at the start of you tests. Because it's in memory you don't have to worry about having a database server, it's fast, and you can load it with data specific to your test. \n\nI use mocks quite a bit and whilst they are great for unit testing a class, in some cases they are not. They can also miss lead quite easily. It's not uncommon for something that works with mocks, to not work when integrated. The reasonnfor this is that you are loading the mock with certain expectations and responses, which you may have wrongly intepreted from the thing that the mock represents.\n\nDon't get me wrong, I like mocks and use them quite a bit. But in doing so you must never assume that because something is unit tested, it's correct. It does increases the chances, but on integration tests actually give you 100% assurance.",


More about “Unit tests and database” related questions

Unit tests and database

This question about unit tests sparked another thing that's been bothering me. I've gone back and forth on three ways to do unit tests when hitting a database. Create mock objects and plug them in...

Show Detail

Fail the unit tests when the database schema, and entity are changed, but unit tests are not changed

Following is the exact scenario in my application: There are several C# methods in the codebase which are using Entity framework to talk with SQL database. Unit tests are written against all metho...

Show Detail

Why not hit the database inside unit tests?

I've read in blogs that the database should not be hit when the unit tests run. I understand the theory, however say i have complex store procedures that are part of a business domain operation. I ...

Show Detail

database operations as a pre-requisite to unit tests?

How do I create a unit test that partially makes use of database unit tests but is called from a regular unit test? Yes, perhaps they may not be unit tests; you may wish to call them integration t...

Show Detail

Mock Room database for Unit tests

I'm trying to make some Unit tests for my business logic. Data is read and written to Room database, so the logic depends on what's inside my database. I can easily buildInMemoryDatabase and test...

Show Detail

MSTest unit tests and database access without touching the actual database

In my code I interact with a database (not part of my solution file). The database is owned by a separate team of DBA's, and the code we developers write is only allowed to access stored procs. How...

Show Detail

Prepare database data before running all unit tests

I'm creating unit tests using PHPUnit in Laravel. Upon creating unit tests, I encounter that on some test I need to prepare database data such as selecting existing records, inserting new record an...

Show Detail

Using Database in Unit Tests

I was running into this error An attempt to attach an auto-named database for file C:\&lt;...&gt;\Out\MessagesDB.mdf failed. A database with the same name exists, or specified file cannot be opene...

Show Detail

Are the tests that MsTest generates actual unit tests?

Visual Studio 2010 generated a bunch of unit tests for me which seems to be handy, but I question whether they are actual unit tests. For example, it generated a test it called SaveTest which exec...

Show Detail

Should unit tests in Test Explorer connect to a database?

Should unit tests in Test Explorer connect to a database? I can execute the same code outside of the test case and it correctly inserts into the database. When trying to test the repository (that

Show Detail