I have recenlty posted a blog article on my implementation of unit testing with Csla, views on Test Driven Development and a usage of the TypeMock dynamic mock library that helped me generate some of my tests.
I would like to hear from feedback from folks that had more expirience with Csla than I have, as well as alternative approaches to Unit Testing with Csla.
Original post can be found here:
http://www.nermins.net/PermaLink,guid,d9a9fa9c-a700-4157-9c5e-59119bf0ea08.aspx
Regards,
Nermin
Also, if you look at the DeepData sample from my site you can see a technique by which you can externalize the opening of the database connection, the setup of the command and the creation of the datareader. Then the business object only deals with a pre-opened datareader.
This is relatively easy to mock, because you can create a mock object that doesn't open a db or command, but does create a mock datareader with test data, so your object is populated from it.
Same concept can work for insert/update - though obviously the data goes into the ether because there's no actual database.
Rocky, “the.next.peter.parker” I would like to thank you both on your recommendations. Looking at how it simplifies mocking process, I couldn’t stop thinking “How come I didn’t think of this?” But hey, this is why we post issues we have to newsgroups. Following your example (I did not use the one with DTOs – too much coding for me, without any obvious advantages I can see at this time) I modified the code in the PTracker sample under ProjectList Fetch() to see what I get from this:
private void Fetch(string nameFilter)
{
RaiseListChangedEvents = false;
DataFactory df = new DataFactory();
using(ProjectListData data = df.GetProjectListDataObject()) {
SafeDataReader dr = data.GetProjectList();
IsReadOnly = false;
while (dr.Read()) {
ProjectInfo info = new ProjectInfo(
dr.GetGuid(0),
dr.GetString(1));
// apply filter if necessary
if ((nameFilter.Length == 0) || (info.Name.IndexOf(nameFilter) == 0))
Add(info);
}
IsReadOnly = true;
}
RaiseListChangedEvents = true;
}
Code above is simpler than the original or the refactored code I had (only a single using block, and no ADO.NET dependencies) Test is then as simple as:
[Test]
public void LoadsOne()
{
Mock mockProjectListData = MockManager.Mock(typeof (ProjectListData));
mockProjectListData.ExpectAndReturn("GetProjectList",
new ProjectListFetchOneDRStub().GetDataReaderStub());
mockProjectListData.ExpectCall("Dispose");
ProjectList item = ProjectList.GetProjectList();
Assert.AreEqual(1,item.Count);
}
Basically I just mock the ProjectListData and assure that I replace the SafeDataReader returned by “ProjectListData” object with the one I need for the test (one created by ProjectListFetchOneDRStub().GetDataReaderStub()). Second expectation is assuring that the Dispose() is called on ProjectListData object.
As far as the recommendation to not use Sqlxxx objects but generic interfaces instead, I generally use Enterprise Library DAAB as my data access library which does that for me. In that example I was just refactoring the original PTracker project which had Sqlxxx implementation which I did not modify for simplicity and easier of comparison to the original.
Thanks,
Nermin
Copyright (c) Marimer LLC