Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you test your business objects?

I am wanting to implement automated testing, using the Microsoft testing framework in Visual Studio, for my software development projects. I have created some tests, and all in all, it's pretty easy to use.

What are some better practices for testing business objects, more specifically ones that read and write to a database.

Is it best to setup a separate test database, from the development database, where the user interface is tested from, and just test against that database? Basically just filling it with junk data.

Is it better to embrace some type of clean-up after yourself mentality, meaning, if I am testing the AddUser method, do I add the User, check my tests, and then delete the User?

Do you test each of the CRUD methods in a single test method?

Lastly, what about the individual business rules like verifying strings are of the correct size, start dates are less than end dates, the CustomerId is a correct Customer and so on.

I realize this is a pretty broad question ... just looking for some direction ... taking baby steps.

More information...

Lot's of good answers! I'm not sure I would be able to pull off a mock database. I am using CSLA as the framework for my objects. It would take some serious refactoring to make this testable with mock objects. I'm going to look into this. Though, at some point, I do want to test the database interaction ... when using a mock database, where/when would you actually test the database communication?

One other question ... is it best to keep each test method non-dependent on other tests?

like image 722
mattruma Avatar asked Feb 14 '09 03:02

mattruma


2 Answers

Ideally, you would have business objects that do not directly access the database, but use helper objects or some kind of ORM (Object-relational mapping) framework. Then you can test your BOs without a database, possibly mocking some helper objects. That is probably the cleanest way, because you avoid the complexity of a real DB, and really only test your business logic.

If you cannot avoid combining business rules and DB access into one class (probably a problematic design, but sometimes hard to avoid), then you have to test against a DB.

There pretty much the only reasonable option is to have a separate DB for automatic testing. Your test methods should delete everything on setup on setup, then load all their data, do the test and verify results.

Don't even think about trying initialise the DB once and then run all tests on the same data. One test will accidentally change data, and other tests will mysteriously fail. I've done that and regretted it... Each test really must stand on its own.

To do all this, I strongly recommend some kind of DB testing framework. These help you to clean the DB, load necessary data, and compare query results to expected results. I use DBUnit (for Java), but there are many others for other languages.

like image 159
sleske Avatar answered Sep 29 '22 23:09

sleske


I would recommend implementing your business objects so that they are unaware of the database. Use methods on the data access layer that can save/retrieve business objects properly depending on their type (i.e., it has an internal mapping between the tables and the objects they correspond to). When testing your business object itself, then you need not worry about the database at all. Simply create the object, perhaps use reflection to set private fields, and conduct your test on the object.

When testing code that needs to interact with the data access layer, use mocking to create a mock data layer and set up expectations on it to return the desired objects or respond properly to saves. You may need to develop your data layer to an interface (or wrap it with a mockable class if using a rigid framework that doesn't support mocking directly). Most mocking frameworks require that methods be virtual to allow a mock implementation to be created. Using interfaces forces the methods in the implementing class to be virtual so mocking is much easier.

like image 23
tvanfosson Avatar answered Sep 30 '22 00:09

tvanfosson