In TDD, I've been testing business logic by mocking data access functionalities. but in reality I need the layers below the business layer also to be implemented for the application to work.
should I be implementing data access layer using TDD?
Based on the discussions I've seen on web,开发者_如何学JAVA unit tests should not be connecting to any external resources such as databases, web services etc.. If they connect, then they become integration tests.Could someone shed some light on this please.
Thank you very much.
You are right, contact to the outside makes it integration test, but that contact is important to test as well. Using TDD, it should be exposed to you, that the contact surface is as small as possible. That can be achieved by using wrappers for each record, or similar methods.
If you're using something like Hibernate for example and if you have any kind of logic in your DAO you can mock out the calls to eg Session and Query and unit test without hitting the database.
If you want to test the queries themselves you could use an in-memory database and something like DbUnit. I would count these as integration tests and run them separately as they tend to take longer.
Here's an example of a typical Java Spring/Hibernate DAO method with some logic you might want to test:
public List<Entity> searchEntities(final String searchText, final int maxResults) {
String sql = "select * from entity where field like :text";
Query query = sessionFactory.getCurrentSession().createSQLQuery(sql);
if (maxResults != 0) {
query.setMaxResults(maxResults);
}
query.setString("searchText", "%"+searchText+"%");
return query.list();
}
Using a mocking framework you could mock sessionFactory, session and query and create a unit test that has expectations that query.setMaxResults is only called if it doesn't equal 0 and that query.setString is called with the correct string value. You could also assert that whatever is returned from query.list() is the thing returned by the method.
However, this is making you test code coupled to your implementation of this method. Also, if your DAO method has a lot of logic in it then you should consider refactoring and maybe moving this logic to a service layer where you could unit test it separately from any database interaction.
You can use Dev Magic Fake to fake the DAL so you can Work with TDD as you need without writing any code for the Fake DAL for example
Just add a reference to DevMagicFake.dll and you can code the following:
[HttpPost]
public ActionResult Create(VendorForm vendorForm)
{
var repoistory = new FakeRepository<VendorForm>();
repoistory.Save(vendorForm);
return View("Page", repoistory.GetAll());
}
This will save the VendorForm permanent in the memory, and you can retrieve it anytime You need, you can also generate data for this object or any other object in your model, without writing any code to that operation, so now you can make TDD as you already finish your DAL for more information about Dev Magic Fake see the following Link on CodePlex:
http://devmagicfake.codeplex.com
Thanks
M.Radwan
精彩评论