CSLA.NET VB and C# Visual Studio Class Templates

October 17, 2008 09:02 by ndibek

As a part of upcoming CSLA.NET 3.6 beta 2 release we have added one more feature - Csla.Net Class Templates for VB.NET and C# integrated in Visual Studio 2008.  So for example, when you select "Add New Item" in Visual Studio you get following options: 

Each of the class templates from the dialog above generates a Csla object with the template selected.  So for example, for selected CommandObject template in the dialog above with the selected name CommandObject2 you get the code generated below:

using System;
using System.Collections.Generic;
using System.Text;
using Csla;
namespace ClassLibrary1
{
[Serializable]
public class CommandObject2 : CommandBase
{
#region Authorization Methods
public static bool CanExecuteCommand()
{
// TODO: customize to check user role
//return Csla.ApplicationContext.User.IsInRole("Role");
return true;
}
#endregion
#region Factory Methods
public static bool Execute()
{
if (!CanExecuteCommand())
throw new System.Security.SecurityException("Not authorized to execute command");
CommandObject1 cmd = new CommandObject1();
cmd.BeforeServer();
cmd = DataPortal.Execute(cmd);
cmd.AfterServer();
return cmd.Result;
}
private CommandObject1()
{ 
/* require use of factory methods */ 
}
#endregion
#region Client-side Code
// TODO: add your own fields and properties
bool _result;
public bool Result
{
get { return _result; }
}
private void BeforeServer()
{
// TODO: implement code to run on client
// before server is called
}
private void AfterServer()
{
// TODO: implement code to run on client
// after server is called
}
#endregion
#region Server-side Code
protected override void DataPortal_Execute()
{
// TODO: implement code to run on server
// and set result value(s)_result = true;
}
#endregion
}
}
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Implementing MVC Site using Csla and ExtJs - Part 3 - UI, ExtJs Customer DropDown List

September 10, 2008 09:32 by ndibek

This is the third part in series "Implementing MVC Site using Csla and ExtJs".  The first two parts can be found here:

Part 1 - Introduction 

Part 2 - Solution Structure 

 

In the previous 2 posts I mentioned decisions behind some of the technologies used in the demo as well as the file structure.

 If you remember I stated that url reguest like:

http://server/<Controler>/<Action>/<Parameter(s)>

is mapped into Controller.Action(Parameters...) call.

So lets take a look at the  our example - what happens when we click on Customer link:

As you can see the url follows the pattern we mentioned above.  So with the assumption from above we would presume that the CustomerController.List() method would be called.  Lets take a source code of that Action/Method to se how do we get to the view:

Where is the beef? List method seems to create some SelectList object, and then passes it to the method called View as a parameter.  Hmmm...  OK, method View probably results in View called List being rendered, and we are passing it SelectList for perhaps databinding...

Where is CSLA code?  Well, customerFactory is an instance of ReadOnlyListFactory class.  RetreiveAll() returns CustomerList instance which is ReadOnlyBase implemenation.  But why not use  CustomerList.RetreiveAll() - factory method?  Instead of using Factory Method design patern, we are using Abstract Factory, moving Create(), and Fetch() outside of our Csla BOs, for the purpose of easier Unit Testing.  I will explain the details of this in one of the future posts that has to explain the whole process of testing all of the app layers in Csla - which will probably be the best part of this demo.

For now, all we need to know is that there is AbstracBusinesstFactory class that defines following: 

 
and then the ReadOnlyListFactory.RetreiveAll() looks like this: 
 
and cutsomerFactory is instantiated with, in controller's constructor with:
 
var customerFactory = new ReadOnlyListFactory<CustomerList,CustomerInfo>();
 
Again all we care for now is that customerFactory.RetrieveAll() serves same purpose as customerList.RetriieveAll().
 
What does then SelectList object do?  It is used by Html.DropDownList() helper method of the MVC frameowrk (there are number of others) that renders html  <select>element for us.  All that SelectList does is it takes the IList implementation, like CustomerList, the other two parameters being Key Value (CustomerID)and  Display Value (CustomerName), for SelectList.
 
Lets now take a look at the Html source of the List.aspx: 
 
This actually is all of the Html that is in the List.aspx view, by the way.  I will explain later how the Order and OrderDetials grid "Magically" appear on it.
 
  

But wait, when I run the sample site the drop down I see has a different style from standard windows drop-down.  In addition to that we can see that the drop down has a type-ahead, kind of like Intelisense...

How come?  When I look at the html source very simple <select> element is rendered... 

Simply put this is where ExtJs comes in.  We have used ExtJs DropDown control, that simply can "inherit" from the Html element/instance, and extend it to implement some new functionality, like in this case.  What complicated JS did we have to write to do this, you might ask?
 
Well here it goes, this is all that is needed:
 
It appears that the script creates an Instance of Ext.form.ComboBox() class (I know, I know some of you might say: "But wait JS does not support classes".  Well ExtJs does, and so does JQuery, and Prototype - 3 most popular Ajax libraries on the planet). And it passes parameters, like typeAhead: true, and transform:'customerList'.  TypeAhead is obvious, but transform parameter is interesting.  It tells ExtJs.for.ComboBox class which html <select> element it needs to enhance/transform.  And that is all.  Oh, by the way there is an extra call that registers JS function refreshOrderGrid() to listen to "select" event on our drop-down, after the constructor.  That is the extCombo.addListener() call.
 
But Nermin, we should not use JavaScript, although that chunk of code looks cool.  Well then neither should folloing companies, all of which have sites built on top of ExtJs:
 
Adobe, Aetna, AIG, Alcatel-Lucent, Amazon.com, Best Buy, Boeing, Borland, CA, Canon, Capgemini, Cisco, CNN, Dow Jones & Co., EMC, Fidelity, General Electric, Hallmark, HP, HSBC, IBM, Mott MacDonald, NATO, NetApp, Nortel, Northrop Grumman, Panasonic, Pixar Animation Studios, Qualcomm, Inc., S&P, SAP, Siemens, Sony, Symantec
 
The difference between the JS that used to get us burned in the old ASP days and ExtJs is that ExtJs is extremely simple, it is used strictly for UI rendering - no business logic in JS, and allows for all of the modern language constructs in JS.  Building extension methods, overloads, custom expressions is easier in ExtJs than in C#.  And would you rather have unreadable and unmaintainable Java Script that some of the Web Forms control generate (that by the way is not compatible with all of the browsers, and can't be touched - it is generated), or would you use this easily extensible JavaScript  library directly.  Unlike Web Forms generated script this is easily manipulated for style, adding new features etc.  One can inherit from Ext.form.ComboBox class create its own extenions override existing methods behaviors.  Limit is only your cretivity.
 
This will just get more interesting in the next post when we discuss the "magically" appearing Order, and Order Detail grids. Grids that support everything that ASP.NET Web Forms GridView do and lot more.  And it is my humble hope that the article will prove to you that this results in by far simpler and easier to maintain code, that is easily testable, and more stable.
 
Source for this demo can be found at:

ExtJsDemo.zip (2.58 mb)

 
 
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Implementing MVC Site using Csla and ExtJs - Part 2 - Solution Structure

September 10, 2008 06:34 by ndibek

This is the second article in "Implementing MVC Site using Csla and ExtJs".  There will be few more!  First one can be found at:

Part 1 - Introduction 

Unfortunately I have to get through this part and UI before I starttalking about my favorite parts TDD using MVC, Unit Testing in Csla,Design of the DAL in this example to support testability, and newfeatures of Csla 3.6 that support Unit Testing, like ObjectFactory. This part being UI, and how Csla BOs get rendered in MVC app that usesExtJs Ajax library.  Fortunate part about that though is that I hopemany of you will find the UI part to be something different and cool! 

So lets take a look at the ExtJsMvc solution (image on the left).  It includes 3 projects:

- ExtJsCslaDemo.Web (web site)

-  ExtJsCslaDemo.Web.Test (Unit tests library built on top of xUnit.net and RhinoMocks)

- Northwind.Data (Linq DAL + few classes that make testing a DAL breeze, on all on top of Northwind sample DB - attached in App_Datafolder)

 

Key to any Web MVC project are the following 3 folders:

- Controllers (controller classes are in this folder)

- Views (This folder contains all the Views/Pages to be rendered inthis application.  Views are grouped in Subfolders that hold the samename as a controller that is in charge of that view.  SO for example,you have a Customer subfolder of the Views folder that holds veiws thatthe CustomerController controls - a single veiw called List.aspx).

- Models (This is the place for your BOs that the Views will render- in this example, this is where I placed the Csla classes, butobviously for any solution that ).

 

As far as controllers our focus is going to be strictly onCustomerController, and OrderController.  HomeController is just thedefault one that gets created by the MVC project wizard, andAccountController is the one that takes care of security (login,changing passwords, etc).

 When it comes to views just notice that Customer Controller has oneview (List.aspx), while OrderController has no views in the Views/Orderfolder.  I will explain that part later in the UI section. 

 Source for this demo can be found at:

ExtJsDemo.zip (2.58 mb) 

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Implementing MVC site using CSLA and ExtJs – Part 1 - Introduction

September 8, 2008 02:19 by ndibek

There are many folks who simply believe that one can’t develop a Test Driven MVC site using CSLA.NET.  Two just simply won’t work together!  CSLA.NET is just too tightly coupled! MVC and TDD require a specific DI architecture that simply cannot work with CSLA’a mobile objects.  Well we are here to disprove those assumptions.  In addition this will be the first step towards creating a CSLA standard bearer demo site in MVC – Project Tracker. 
This is going to be a multi-part post where each post will describe different parts of this MVC application, and different Csla integration points – Introduction – MVC part, Json UI, Unit Testing, and the choice of Repository Pattern for this demo. 

History

You can download the source here.   But before we go through the example what was my motivation behind this.  ASP.NET forms few years back represented one of the largest productivity increases in web development.  But soon we discovered that complex layouts require complex web controls and pages.  In addition to that none of the complex controls are easily extended, beyond simple tasks that are built into the control itself (style, and similar changes on a grid control, for example).  Awkward event model that was supposed to make it easier for Windows developer’s to migrate to web became another bottleneck.  The largest problem was that although we were coding ASP.NET web apps in .Net languages, our deployment target was still a combination of JavaScript/Html, the part that was almost completely abstracted away and hard to get to.
That abstraction was a reason for making any extensions to existing ASP.NET web controls and libraries harder.  For some controls like grid control for example, we did not even know what html is going to be rendered at run time.  It depended on browser type, version, time of the day,…  Worst of all when Ajax came out, technology that heavily depended on JavaScript/Html ASP.NET started falling behind some of the competitors.  For sure we got few little things like “Update Panels”, and little auto-completion fields (that somebody else built for us), but building anything yourself required JavaScript.  Not just that but integrating that JavaScript to run with the ASP.NET Server components was not the easiest thing in the world.

Concepts

That is where the idea of MVC came to life (actually few other competitors have had successful implementations before .Net, and even on .Net platform there was a Monorail platform that was available years before ASP.NET MVC).  Instead of having a web page/form respond to URL requests and Html form posts, they introduced a controller object.  And they came up with a simple mapping that allowed us to build rather simple public methods on the controller and map Html form values or URL query parameters to that method as parameters or directly onto a DTO object inside that method.  That separation resulted in easier program control flow from server to the web page, and breaking away from server side control model.  Pages became views, in charge of nothing but rendering a content and presenting it to the user, as well us posting changed data to the controller.  There was no more any complex business logic on the page itself, or complex "server event flow".

So if you would see a URL like:
http://server.com/Products/Edit/5,
that would map into a ProductController.Edit(5) action method.

I am not going to go though full introduction of MVC here.  You could go through the documentation/examples on following site:
http://asp.net/mvc
http://www.codeplex.com/aspnet
http://weblogs.asp.net/scottgu/archive/tags/MVC/default.aspx

Demo App

So this example (screen below) utilizes MVC Framework for ASP.NET and is built on top of CTP 5.

ExtJsDemo.zip (2.66 mb)

 

 At the back end of this demo is a copy of the Northwind database (found in App_Data folder).   It is a simple screen with 3 ReadOnlyList object.  On the left you will see a Drop Down with a list of customers.  Once a Customer is selected, we load a list of Orders for that Customer.  When selected, order displays its order details in the drop down below.  

All of the actions on this screen utilize Ajax calls.  Now for the choice of Ajax framework used here.  MS Ajax as it is built is out of questions.  It was built to support web form post back/callback model, which really cannot take advantage of the MVC model.  And simply put it is not very easy to use outside web forms.  AS far as MS MVC Ajax – MS folks have just started working on it for the latest CTP 5 release, and they are years behind ExtJs, Jquery, and other libraries.

That leaves us with JQuery and ExtJs (at least fro now).  However, one good thing about MVC framework, is that is built from scratch to be easily extensible, and to play well with any of the third part tools.  You will see in some of my future posts on this demo that I utlize xUnit.net and excellent unit test framework that drives the innovations in .Net unit testing world.  Not nUnit, or MSTest. Or for the same reason choice of RhinoMocks as the Dynamic Mocking framework.  For the same purpose in the future versios of this demo we will utilize StructureMap as a Dependency Injection framework instead of MS Unity.  All of these play very well with MVC and prove how extensible it is.  But enough about that - lets mov on with our demo solution.

There are conceptual differences with the JQuery and ExtJs.  JQuery is more focused on building dynamic html with its Ajax calls to the server, and dynamically inserting modifying parts of the page in response to Ajax action.  If for example you want to render a custom modal pop-up dialog inside the page, as a result of action on the page JQuery will submit action to the server – controller, that will then render the content of the dialog back to the page.  JQuery will then insert the dialog inside the modal frame control and display it.  That is more in line with traditional Ajax development.


My choice of the ExtJs had something to do with a lot of CSLA developers coming from the Windows world.  ExtJs actually provides us with the visual components/controls, like grids, drop downs, tabs, windows, etc…  This controls utilize JSon to submit modified data to the server, and receive the content they need to render from the server.  So instead of receiving a content of the grid control, for example, as a partial html page (table element), from the controller action, ExtJs grid actually receives what is called a JSon reader, and binds it to a sortable/ customizable grid control.


That way our server MVC model; actually utilizes more of a familiar control/event model on the client and I would actually say that for Windows developers this might be even easier migration path than the web forms.
In the next post I will be talking about UI portion of this demo, provide details of how we convert Csla objects into Json stream, send it from the Controller action and then utilize it within ExtJs Drop Down and Grid controls.  This post will mostly be about server side unit testing for controller and routes.  The fourth and final post should focus on the choice of Data Access Layer pattern – repository, and its integration into Csla code.

ExtJsDemo.zip (2.66 mb)

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Currently rated 4.7 by 3 people

  • Currently 4.666667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

TDD/Using Mock objects with CSLA.Net (Round II)

May 9, 2007 18:09 by ndibek

I have received few comments on the first post, one of them being from Rocky Lhotka the creator of the Csla.Net framework.  He basically pointed to his advanced data sample (DeepData.sln available for download at www.lhotka.net). 

The idea is that if we encapsulate all of the ADO.NET constructs required to fetch/update a single table into a “Data object” and move it from the Fetch() method of Csla object (some might find this similar to Table Data Gateway pattern), then the only thing we have to mock is that Data object. 

In addition setting expectations would be lot simpler, since everything is encapsulated.  So, instead of me talking about it lets look at how that changes the Fetch method of the ProjectList class defined in PTracker sample:

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) .  So lets take a look at what happened.  We stopped using the Database class (that functionality will move into our Data object – ProjectListData).  We can see 2 new objects constructed in this code: 1.       DataFactory – Factory in charge of instantiating all of the Data objects for our project 2.       ProjectListData – Data object, whose purpose is to encapsulate the ADO.NET constructs, and return a SafeDataReader back to the Ftech() method. 

It is important to note that ProjectListData implements IDisposable interface.  That way as we dispose of it, it will dispose corresponding DataReader, DbCommand and a Connection.  Hence only one using block needed here. Test are 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);

 

[Test(Description = "DataReader returns 3 items but only one should be inserted, based on filter")]

public void LoadsThreeFiltersTwo() {

     Mock mockProjectListData = MockManager.Mock(typeof(ProjectListData));

     mockProjectListData.ExpectAndReturn("GetProjectList",

         new ProjectListFetchThreeDRStub().GetDataReaderStub());

     mockProjectListData.ExpectCall("Dispose");

     ProjectList item = ProjectList.GetProjectList("test");

     Assert.AreEqual(1, item.Count);

}  

As you can see mocking of the fetch process and replacing of the SafeDataReader is only couple of lines of code.  First line defines that we intend to mock ProjectList object.  Second one sets expectation that the method called GetProjectList() will be called.  Result of that call is supposed to be replaced by result of the call to  ProjectListFetchOneDRStub().GetDataReaderStub() in the first test, or the ProjectListFetchThreeDRStub().GetDataReaderStub() in the second test. 

These two methods return our stub DataReaders that contain the test data (source code for these is available in my previous post).  And that is it.  Rather simple!

At the end let me show you the code of our ProjectListData object:

public class ProjectListData : IDisposable {

     private SqlConnection _cn;

     private SqlCommand _cm;

     private SafeDataReader _data;

     private bool disposed;

     internal ProjectListData()

     {

         _cn = new SqlConnection(Database.PTrackerConnection);

         _cm = _cn.CreateCommand();

         _cm.CommandType = CommandType.StoredProcedure;

         _cm.CommandText = "getProjects";

         _data = new SafeDataReader(_cm.ExecuteReader());

     }

     public SafeDataReader GetProjectList()

     {

         return _data;

     }

     #region IDisposable Members

     public void Dispose()

     {

         Dispose(true);

         GC.SuppressFinalize(this);

     }

     protected virtual void Dispose(bool disposing)

     {

         if (!disposed) {

             if (disposing) {

                 // Dispose managed resources.

                 _data.Dispose();

                 _cm.Dispose();

                 _cn.Dispose();

             }

             // Dispose unmanaged resources

         }

         disposed = true;

     }

     #endregion

}

 

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Currently rated 4.5 by 2 people

  • Currently 4.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

TDD/Using Mock objects with CSLA.Net

April 30, 2007 17:29 by ndibek

I mustadmit that I am a huge fan of Test Driven development.  AlthoughI generally use CRC process to design my classes and their interactions, I tend touse TDD process to fine-tune the collaborations between these objects, and generallysimplify my initial object design.  While I know that there aremany skeptics in usefulness of TDD as a software design process, I believe that theyunderestimate one important factor in developer’s arsenal: laziness!  Aftera while each one of us tries to find a way to minimize the number of tests they haveto write per object you implement.  If you build it in its simplestform, minimizing interactions and state permutations you minimize the number of thetests.  In addition tests help us understand how objects is used/howit behaves/interacts with other objects.  And most importantly testthat we write give us that safety net to facilitate change, refactor code withoutconstant worry that we might break existing functionality.  

Mocks on the other hand are the mechanism that assuresthat tests focus on the unit/component being tested and not the components that thisunit interacts with.  When the tested code uses other componentsthings can get quite fragile and the tests will quickly become system tests.  Examplesare classes that use a database, a logging system, web service and any other externalcomponents.  These external components might require a complex setup.For example, in order to run a test that uses a database, we must have a running databasewith the tables and data setup correctly for the test (we must cleanup this data beforeeach test runs).  Too much work for a lazy developer,and more importantly test results easily compromised by factors that are out of ourcontrol.

So mocking in this case sounds like a validsolution.  But what is the problem in implementing this in a CSLAworld?  Well, CSLA has this concept of ‘Mobile Objects’, which meansthat the object is generally created in the (App) Server context, and then serializedto the client.  For example let’s take a look at the way we retrieveProjectList object from the sample ProjectTracker20cs project.

/// <summary>Returna list of all projects.</summary>

public static ProjectList GetProjectList()

{

return DataPortal.Fetch<ProjectList>(new Criteria());

}

or,

/// <summary>Returna list of projects filtered by project name.</summary>

public static ProjectList GetProjectList(string name)

{

    return DataPortal.Fetch<ProjectList>

      (new FilteredCriteria(name));

}

For all of us that use CSLA daily this meansthat the DataPortal is going to instantiate the object of type ProjectList, call appropriateoverride of the method DataPortal_Fetch() definedin the ProjectList,and finally serialize it back to the client where that instance is returned troughthe factory method in question. 

DataPortal_Fetch methodoverrides should resemble something like this:

private void DataPortal_Fetch(Criteria criteria)

{

    //fetch with no filter

    Fetch("");

}

private void DataPortal_Fetch(FilteredCriteria criteria)

{

    Fetch(criteria.Name);

}

private void Fetch(string nameFilter)

{

    RaiseListChangedEvents= false;

    using (SqlConnection cn= new SqlConnection(Database.PTrackerConnection)){

        cn.Open();

        using (SqlCommand cm= cn.CreateCommand()) {

            cm.CommandType= CommandType.StoredProcedure;

            cm.CommandText= "getProjects";

            using (SafeDataReader dr= new SafeDataReader(cm.ExecuteReader())){

                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;

}

Now let’s take a look at how most of the mocking frameworksmock dependencies.  Generally one needs to create an interface onthe object we are mocking, and then pass the reference to that interface to the objectwe are trying to test.  This is essentially the implementation ofthe “Dependencyinjection pattern”, where the actual implementation is passed as this interfaceat run time, or mock object during the tests.  This, as far as Ican tell, applies to NMock, EasyMock,or RhinoMock.

So the problem is that these mocking tools require us tobuild “mockable” objects.   This will not work with CSLA, orat least will not be implemented easily.  The problem is that, ifone wants to mock dependencies such as data access layer components (db connection,data reader, command) one would have to instantiate them on the client side and then“inject” them as arguments into the Factory Method being called, making sure thatthey are somehow serialized to the server side.  And naturally databasecomponents are not serializable.

So, is it possible to mock CSLA dependencies thatreside only on server side and are not serialized back and forth?  Theanswer is “Yes”.  Yes if you use TypeMock.Net library.  Whatis the major advantage of this tool when compared to other .Net mocking tools?  TypeMockuses Aspect Oriented technology to redirect calls from the real code to the mock objectinstantiated.  So how does this work?

Before we try to mock dependencies we have toremember one of the golden rules of Mocking:  “Never to Mock classes/interfacesyou do not own or have source code to”.  What does that mean?   Ihave seen code where developers tried to Mock interfaces as IDataReader (or SqlDataReader)for example.  That interface is too complex and it is not somethingI defined or have control over.  So the first thing I would liketo do is build a class called Database, that encapsulates all of the database communicationin the Fetch() method.  Solet’s do a little refactoring:

private void Fetch(string nameFilter)

{

    RaiseListChangedEvents= false;

    using (Database db= new Database(Database.PTrackerConnection)){

        SqlCommand cm= db.CreateSPCommand("getProjects");

        using (SafeDataReader dr= db.ExecuteSafeDataReader(cm)) {

            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;

}

Let us compare the code above to the original Fetch().  Onecan notice that instead of creating SqlConnection object we created a Database objectpassing its constructor a desired connection string.  You will alsonotice that we are not explicitly “Opening” database connection.  Thatis because the Database class is managing SqlConnection internally and opening itas needed (for example, within the Database.ExecuteSafeDataReader() callas you might notice bellow when we take a look at the Database class).   

In addition you will notice that we have removed the usingblock around the SqlCommand instance.  Again the Database instancemanages SqlCommand objects it creates and disposes them at the time it is disposeditself (together with disposing a SqlConnection).

 Below is a simplified version ofthe Database class.  Some of you might notice s similarity to theDatabase class implemented in Enterprise Library.  I do generallyuse Enterprise Library, and the pattern used in their Data Access Block makes it easierto test/mock DAL objects.

public class Database : IDisposable

{

    private readonly SqlConnection _activeConnection;

    private readonly List<SqlCommand>_createdCmds;

    private bool disposed;

    public Database(string connection)

    {

        _activeConnection= new SqlConnection(connection);

        _createdCmds= new List<SqlCommand>();

    }

    ~Database()

    {

        Dispose(false);

    }

    #region AvailableConnection Strings

    public static string PTrackerConnection

    {

        get

        {

            return ConfigurationManager.ConnectionStrings

                ["PTracker"].ConnectionString;

        }

    }

    public static string SecurityConnection

    {

        get { return ConfigurationManager.ConnectionStrings["Security"].ConnectionString;}

    }

    #endregion

    #region IDisposableMembers

    public void Dispose()

    {

        Dispose(true);

        GC.SuppressFinalize(this);

    }

    protected virtual void Dispose(bool disposing)

    {

        if (!disposed){

            if (disposing){

                //Dispose managed resources.

                foreach (SqlCommand cmd in _createdCmds)

                    cmd.Dispose();

                _createdCmds.Clear();

                if (_activeConnection!= null && _activeConnection.State != ConnectionState.Closed)

                    _activeConnection.Close();

            }

            //Dispose unmanaged resources

        }

        disposed= true;           

    }

    #endregion

    protected  void OpenConnection()

    {

        if (_activeConnection.State!=ConnectionState.Open)

            _activeConnection.Open();

    }

    public SqlCommand CreateSPCommand(string cmdName)

    {

        SqlCommand cm= _activeConnection.CreateCommand();

        cm.CommandType= CommandType.StoredProcedure;

        cm.CommandText= cmdName;

        _createdCmds.Add(cm);

        return cm;

    }

    public SafeDataReader ExecuteSafeDataReader(SqlCommand cm)

    {

        OpenConnection();

        return new SafeDataReader(cm.ExecuteReader());

    }

    public void AddWithValue(SqlCommand cm, string paramName, object value)

    {

        cm.Parameters.AddWithValue(paramName,value);

    }

}

NUnit usesTest Fixture concept to group tests applied to a single unit of code.  Sosince we are going to test the ProjectList object let’s create that Test Fixture:

[TestFixture]

public class ProjectListTest

{

    [SetUp]

    public void Start()

    {

        ///<remark>InitializeTypeMock before each test</remark>

        MockManager.Init();

    }

   

    [TearDown]

    public void Finish()

    {

        ///<remark>Wewill verify that the mocks have been called correctly at the end of each test</remark>

        MockManager.Verify();

    }

}

As you can see in order to use TypeMock inour tests we need to Initialize the TypeMock’s MockManager first and then call Verify() atafter the test has run.

Now we are ready to write our first test.  Generallymy first test is something extremely simple like making sure that the operation returneda result.  So the first test is going to be the one that ensuresthat the ProjectList.GetProjectList() createsand adds a single ProjectInfo object.

[Test]

public void LoadsOne()

{

    ProjectList item= ProjectList.GetProjectList();

    Assert.AreEqual(1,item.Count);

}

This first test does not have any mocks obviously, and ifwe run it we are going to see the following error:

ProjectTracker.Library.Tests.ProjectListTest.LoadsOne: Csla.DataPortalException : DataPortal.Fetch failed (System.NullReferenceException:Object reference not set to an instance of an object.

   atProjectTracker.Library.Database.get_PTrackerConnection() in C:\Development\csla20cs\ProjectTracker20cs\ProjectTracker.Library\Database.cs:line37

   atProjectTracker.Library.ProjectList.Fetch(String nameFilter) in C:\Development\csla20cs\ProjectTracker20cs\ProjectTracker.Library\ProjectList.cs:line73

   atProjectTracker.Library.ProjectList.DataPortal_Fetch(Criteria criteria) in C:\Development\csla20cs\ProjectTracker20cs\ProjectTracker.Library\ProjectList.cs:line62)

  ---->Csla.Server.CallMethodException : DataPortal_Fetch method call failed

  ---->System.NullReferenceException : Object reference not set to an instance of an object.

The error above states that the line where we triedto call new Database(Database.PTTrackerConnection) faileddue to static property PTTrackerConnection trying to access external configurationfile to read a connection string.  So we will need to mock thatcall.  In addition we will need to mock the whole Database instance,since the Database object internally instantiates the SqlConnection (another externalresource not available to us for this unit test).  So let us writethe code that does that.

 [Test]

public void LoadsOne()

{

    Mock mockDb= MockManager.Mock(typeof(Database));

    mockDb.ExpectGet("PTrackerConnection", string.Empty);

    mockDb.ExpectAndReturn("CreateSPCommand", null);

    mockDb.ExpectAndReturn("ExecuteSafeDataReader", new SafeDataReader(GetDataReaderStub()))

         .Args(null);

    mockDb.ExpectCall("Dispose");

    ProjectList item= ProjectList.GetProjectList();

    Assert.AreEqual(1,item.Count);

}

private IDataReader GetDataReaderStub()

{

    return new DataTable().CreateDataReader();

}

We have added few lines to our test.  Thefirst line allows defines the object that we are going to mock.  Followingfour lines define the behaviors of the Database objects that we are going to interceptand replace with our values that we need for the test, therefore taking the databaseout of equation.  As we can see from line:

mockDb.ExpectGet("PTrackerConnection", string.Empty);

We are expecting a Property Get call on the propertycalled PTrackerConection and we want it to return a constant string.Empty.  Thenwe are expecting a method call to “CreateSPCommand”to be called, and want our mock Database to return null (we do not care about theSqlCommand since the mock Database object is not going to be using it anyway).  Followingline is where it gets interesting:

    mockDb.ExpectAndReturn("ExecuteSafeDataReader", new SafeDataReader(GetDataReaderStub()))

         .Args(null);

As you can see we expect that the call to ExecuteSafeDataReaderreturns Data Reader as defined in the GetDataReaderStub() method.  Ifwe run the test now following will be the output:


NUnit.Framework.AssertionException:   Expected:1

  Butwas:  0


at NUnit.Framework.Assert.That(Object actual, IConstraint constraint, String message,Object[] args)
at NUnit.Framework.Assert.AreEqual(Int32 expected, Int32 actual, String message, Object[]args)
at NUnit.Framework.Assert.AreEqual(Int32 expected, Int32 actual)
at ProjectTracker.Library.Tests.ProjectListTest.LoadsOne() in ProjectListTest.cs:line42

Since the GetDataReaderStub() methodis supposed to return a IDataReader that is constructed from the empty DataTable,then the number of items in the ProjectList should be zero.  Moreimportantly we have successfully mocked the data access layer code although our testis still failing (we want to ensure that our test inserts one item from mock Databaseinto the ProjectList).  Proof of successful mock is the fact thatwe are not getting any ado.net exceptions when we run the test – meaning that allof the calls to the Database object are intercepted as we expected.  Assuringthat test is successful will require us to modify the GetDataReaderStub() methodto create a DataTable with the signature that is expected in fetch method, and withthe number of the records that are expected in the result (1). 

But before we do that let’s first clean the test code.  Igenerally do not want to crowd the code in the actual test with bunch of the detailsof the internal mocks.  In  addition it seemsthat there will be a common pattern in the way we fetch records, so I believe we canextract the Mock calls to a helper method called MockDatabaseFetchCall().  Alsoif this is to be method that is shared between multiple Test Fixtures we should moveit outside of this Test Fixture.  Let’s see how our code looks likeafter that refactoring.

internal class MockHelper

{

    public static void MockDatabaseFetchCall(string connectionName, int noOfAddInParamCalls, IDataReaderStubFactory drFactory)

    {

        Mock mockDb= MockManager.Mock(typeof(Database));

        mockDb.ExpectGet(connectionName, string.Empty);

        mockDb.ExpectAndReturn("CreateSPCommand", null);

        mockDb.ExpectCall("AddWithValue",noOfAddInParamCalls);

        mockDb.ExpectAndReturn("ExecuteSafeDataReader",drFactory.GetDataReaderStub())

            .Args(null);

        mockDb.ExpectCall("Dispose");

    }       

}

We can see that the MockDatabaseFetchCall() methodhas 3 parameters.  The necessity for the first parameter is dueto the fact that our Database object has two “connection string” properties: “PTrackerConnection”and “SecurityConnection”.  Argument connectionName, allows us tospecify which of the two we will mock.  We can see that the secondparameter is related to the new line in our method:

mockDb.ExpectCall("AddWithValue",noOfAddInParamCalls);

What does that line mean? The line states that weexpect a call to the method called AddWithValue() noOfAddInParamCalls times,and that we are going to ignore parameters or the return value.  Wejust want to ensure that the calls are made.  But the method AddWithValuedid not exist in our original definition of the Database class.  Wehave added this method as a part of this last refactoring. Here is what it does:

public void AddWithValue(SqlCommand cm, string paramName, object value)

{

cm.Parameters.AddWithValue(paramName,value);

}

In some of the Fetch() methodswe want to pass parameters to the stored procedure that allow us to filter the datawithin stored procedure.  Then our Fetch call signature changes.  Foreach parameter there is an extra call to the AddWithValue() method.   

Now let’s move onto the third parameter:  IDataReaderStubFactorydrFactory.  It is an interfacethat defines a single method:

internal interface IDataReaderStubFactory

{

    SafeDataReader GetDataReaderStub();

}

Basically since MockHelper.MockDatabaseFetchCall() isa shared method, and every list object’s (BusinessListBase<T>, or ReadOnlyBase<T>)Test Fixture will have one or more IDataReader Stubs, I decided to implement themas an interface.  Here is the implementation for our “one recordfetch” of the ProjectList:

public class ProjectListFetchOneDRStub : IDataReaderStubFactory {

    public SafeDataReader GetDataReaderStub()

    {

        DataTable stubTable= new DataTable();

        stubTable.Columns.Add("pk",typeof(Guid));

        stubTable.Columns.Add("desc", typeof (string));

        stubTable.Rows.Add(new object[]{Guid.NewGuid(),string.Empty});

        return new SafeDataReader(stubTable.CreateDataReader());

    }

}

As you can see we are actually generating a DataTablewith columns that match structure expected in ProjectList.Fetch() method.  Inaddition we are generating a single row of data.

Taking all this into account our modified test code shouldlook like this:

[Test]

public void LoadsOne()

{

    MockHelper.MockDatabaseFetchCall("PTrackerConnection",0, new ProjectListFetchOneDRStub());

    ProjectList item= ProjectList.GetProjectList();

    Assert.AreEqual(1,item.Count);

}

After running this test we can see that the test passes.  Projectlist successfully fetches and inserts one item.  Now this lookslike a lot of work for our first test, but note how easy it is to create future testsof this type.  Let’s say we want to test the other path in creationof the Project List – ProjectList.GetProjectList(stringname).

[Test(Description= "DataReader returns 3 items but only one should beinserted, based on filter")]

public void LoadsThreeFiltersTwo()

{

    MockHelper.MockDatabaseFetchCall("PTrackerConnection",0, new ProjectListFetchThreeDRStub());

    ProjectList item= ProjectList.GetProjectList("test");

    Assert.AreEqual(1,item.Count);

}

The main difference between this one and our firsttest, besides us calling the GetProjectList(“test”) withthe string argument is that we pass a different IDataReaderStubFactory implementation– ProjectListFetchThreeDRStub.  Andthat class is defined as:

public class ProjectListFetchThreeDRStub : ProjectListFetchBaseDRStub {

    public override SafeDataReader GetDataReaderStub()

    {

        DataTable stubTable= GetStubTable();

        stubTable.Rows.Add(new object[]{ Guid.NewGuid(), "testis important" });

        stubTable.Rows.Add(new object[]{ Guid.NewGuid(), "" });

        stubTable.Rows.Add(new object[]{ Guid.NewGuid(), "thistest record will not be included" });

        return new SafeDataReader(stubTable.CreateDataReader());

    }

}

You will notice that I have followed my usual behavior andhave refactored ProjectListFetchThreeDRStub (when compared to original ProjectListFetchOneDRStub).  Ihave extracted the code that instantiates a DataTable, and creates column structureinto a method called GetStubTable().  This method was moved intoa base abstract class called ProjectListFetchBaseDRStub, and both ProjectListFetchThreeDRStub,and ProjectListFetchOneDRStub now inherit from it.  Here is thecode of the base class:

public abstract class ProjectListFetchBaseDRStub : IDataReaderStubFactory {

    public abstract SafeDataReader GetDataReaderStub();

    protected static DataTable GetStubTable()

    {

        DataTable stubTable= new DataTable();

        stubTable.Columns.Add("pk", typeof(Guid));

        stubTable.Columns.Add("desc", typeof(string));

        return stubTable;

    }

}

Second test also passes.  Althoughthe we have a SafeDataReader with 3 rows only the first one has a Name that beginswith “test”. 

We can use the same IDataReader Stub to construct the ProjectInfotests, like:

[TestFixture]

public class ProjectInfoTest

{

    [Test]

    public void AssureFieldsMapped()

    {

        SafeDataReader dr= (new ProjectListFetchOneDRStub()).GetDataReaderStub();

        dr.Read();

        ProjectInfo info= new ProjectInfo(

            dr.GetGuid(0),

            dr.GetString(1));

        

        Assert.IsNotNull(info);

        Assert.AreEqual(string.Empty,info.Name);

    }

}

Again this is a rather simple test just to show youone of the possible patterns to use in BusinessBase<T> or ReadOnlyBase<T> tests.  Onceyou have your object constructed from the Data Stub you can run tests that involvebusiness logic, state and behavior of the object.

One might notice that there was a possibility of mockinga DataPortal itself within ProjectList.GetProjectList() method.  Twoimportant issues with that path are that first we would not be testing the code runningwithin the Fetch() method,and the necessity to change an accessibility of constructor of the ProjectList classfrom private to public (to have Mock DataPortal return an instance). 

In future posts I will explore mocking of the portions ofthe code that perform DB insert/update/delete, as well as more efficient way of generatingIDataReader Stubs.

 

>>
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Currently rated 4.0 by 2 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5