The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Unit testing and stubs

here goes :

I want to provide a stub class for testing my business objects so they dont need to be concerned with the database
and i'm wondering the best way to do this.  I am using NUNIT and have set up a dataaccess object factory like so

#if UNIT_TESTS

public class DAOFactory
end

#else

public class DAOFactory
end

#elseif

so it creates the first one which would not create a db connection if we are unit testing. 

does anyone have a better solution to this ? or is this perfectly acceptable ?

I thought of using a provider pattern so you create a business object and pass it its dao object not quite sure
whats better. 

ow do you all do this sort of thing ?
Andy D Send private email
Monday, November 13, 2006
 
 
I don't ever use ifdefs for unit testing because code should never know it's being unit tested.

Usually tests are run from a harness where you know you are running a test. So I usually give the factory the object it is supposed to return. For database stuff I use an inmemory variant. The factory returns the right one for the environment and all the code using the factory works like normal.
son of parnas
Monday, November 13, 2006
 
 
Good point about objects not knowing they're being tested, never thought about that. 

The dffeent factories were to test the business layer objects.  I think a more acceptable solutionwould be to provide the business object with a datalayer object and then this would treat it as the same e.g. in my test files

businessobject.dao = daoTestStub

then I could call the functions on the business object
and test.

just interested in all the different approaches to testing objects that normally connect to a db without setting up an entire test database...

thanks for the comments.
Andy D Send private email
Monday, November 13, 2006
 
 
I would think it would be tremendously helpful for a CRUD based application to have a (perhaps small) database to unit test against.

Anything you 'simulate' out will have to be re-tested once the 'real' thing is available.  So it just depends on how difficult it is to generate and validate the 'simulated' interface, versus creating a 'real' (but limited) one in the first place.
AllanL5
Monday, November 13, 2006
 
 
> I think a more acceptable solutionwould be to provide
> the business object with a datalayer object and then
> this would treat it as the same e.g. in my test files

I typically use a database layer factory as that encapsulates knowledge of the different databases, including inmemory, in one place. If you pass the object in the constructor you have to know how to create the different variants everywhere.

The downside to my approach as this object is typically a singleton I have to reset the factory between each test to make sure I am always starting with a known clean state. Just different tradeoffs, but I think the constructor approach doesn't scale well over time and it is hard when there's a lot of configuration.
son of parnas
Monday, November 13, 2006
 
 
Thanks for these they are realy helpful,

I am definitely torn between the idea of a factory based approach or just creating a unit testing db....
Andy D Send private email
Monday, November 13, 2006
 
 
I do something like this...

public interface DBFactory
...
public class DBFactoryImpl: DBFactory {
    public static DBFactory Instance = new DBFActoryImpl();
...

So my production code uses DBFactoryImpl.Instance which is the real factory in production.  In my unit test setup, I do this:
DBFactoryImpl.Instance = new MockDBFactory ...
so I can mock the database calls.

No conditional compiles required!

I do this mostly to get fast-running unit tests.  To test my stored procedures, I also use a test database with a suite of slow-running DB tests.

HTH
Mike S Send private email
Monday, November 13, 2006
 
 
You probably need mock object here.
There are a lot of mock object frameworks for most development environments.
With mock objects, you don't have to worry about simulating real world behavior, especially when it is expensive, nearly impossible or simply non-deterministic in nature. All you need to do is "mock up" the real-world behavior in code.
Vineet Reynolds Send private email
Monday, November 13, 2006
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz