views:

577

answers:

5

I've got many objects with methods that require database access. We're looking to get into unit testing but are keen to avoid the use of mock objects if possible. I'm wondering if there is a way to refactor the Validate method shown below so that it wouldn't need db access. In the actual application there is usually a fair bit more going on but I think this simplified example should be enough.

We'll learn to use mock objects if we need to but it just seems like a lot of overhead, so I'm looking for alternatives.

    public class Person
    {
        public string Name;

        public string Validate()
        {
            if (PersonDA.NameExists(Name))
            {
                return "Name Already Used";
            }

        }
    }
+6  A: 

Personally I'd just go the mock object route. It's much more flexible and it sounds like you're wanting to go the route of putting test code in your actual object?

Regarless, extract the validation code into a PersonValidator object with a method for boolean isValid(Person). Then in the test code use a mock validator which just returns true or false based on the test case.

NeilInglis
wan't wanting to put test code in the object. Was just wondering if there was some way of refactoring I hadn't thought of that would remove the need for mock objects.
tjjjohnson
A: 

You should just set up a database that is used for the unit testing. If you use mockups for all the data access, you wouldn't actually be testing much? :)

Thorarin
perhaps I have oversimplified the example. Often there would be further checks carried out that do something other than just calling a data access method.
tjjjohnson
+2  A: 

Take a look at dbunit, it's especially set up to populate a small test database so you can use your real objects on a mock database during unit testing. Testing with it is far easier than developing mock objects, far safer than modifying your data access code, and far more thorough than either.

Jim Ferrans
It also allows you to be sure that the actual code works, not just through (simpler) mock objects.
Osama ALASSIRY
+3  A: 

The Person class is hard to unit-test because it has a hidden, static dependency on database access code. You can break this coupling by introducing a dynamic collaboration between the Person and some new type of object that provides it with the information it needs to validate its state. In your unit tests of the Person you can test what happens when it is valid or invalid without hitting the database by passing the Person object "stub" implementations of it's collaborator.

You can test the real implementation, which hits the database, in a separate set of tests. Those tests will be slower but there should be fewer of them because they will be direct translations of accessor methods to database queries with no complex logic of their own.

You can call that "using mock objects" if you like but, because your current design means you only need to stub queries, not expect commands, a mock object framework is a too complicated tool for the job. Hand-written stubs will make test failures easier to diagnose.

Nat
+1 - Unit testing is all about the dependencies and managing them.
duffymo
A: 

Why are you trying to avoid mocks exactly? If you are going to practice unit testing and you have data access code, its going to be easiest to get comfortable with the mock/stub/inject way of doing things.

If it's because you dont want to bring in a mocking framework you could code up some simple stubs as you need them.

Putting your data access code behind an interface will let to avoid the need for a database. Consider using dependency injection to insert the mock or stub data access code during your tests.

Dan
mostly just trying to find out if there are alternatives to mocking for this situation.
tjjjohnson