Adding Custom Themes Support to your WPF Application

November 17, 2008 03:41 by ndibek

The greatest thing about Windows Presentation Foundation is that when compared to Windows Forms, it finally gives us the freedom of easily designing rich UI, that differs from same old Winforms we have been seeing from Win 95 with slight re-styling. We finally have a true vector based UI, that allows us to manipulate each screen element in thousands of different ways through visual effects, animations, scaling, custom layouts etc.

But with this Great Power comes even larger responsibility. Yes we can do all these things, but we also need to assure that our UI looks consistent: If we find this really cool looking buttons library, we need to assure that the Tree Control that we render next to it is styled appropriately to match it, as well as list box, check boxes scroll bars...

We do not want our new UIs to be a mix of every color in the rainbow that look like water color painting of a kindergartner. We need a professional 21st century UIs. Unfortunately most of us developers are superbly creative when it comes to complex algorithms, while our artistic skills lack far behind. Third party controls that support custom Themes might have been a solution to this problem in Windows Forms world, but do we really have to go there in WPF? Another great thing with WPF it adds native support for custom themes. Basically you define your basic layout, drop your controls on the screen, and then similar to CSS in the web world, you define custom styles for your control in the Resources section of your XAML code. If only we had a nice library of WPF styles that we could use...

 



Well that is where "WPF Themes" Library - Open Source Project hosted on CodePlex comes in.  First it is a library of a dozen custom UI Themes for most of the standard WPF controls, allowing us to customize the look and feel of our WPF UI without touching our screens XAML.  What more the library actually comes with a Theme Manager, that allows us to dynamically load and bind our custom Themes at runtime.

How can we use these Themes?  Obviously first download WPF Themes Library project from http://www.codeplex.com/wpfthemes and include it in your WPF Solution. Then it is a matter of you deciding how do you want to select and load custom Theme at runtime.  For the purpose of this example lets presume that we want to allow our Application user to select any of these Themes at runtime in a form of the Drop Down box that we place at, lets say, top right corner of the application main screen.

So lets define this DropDown:


    
    

Ok, so if we look at the XAML above you will notice that there is a stack panel that encapulates the label and a DropDown. But wait, there is no event handler for the SelectionChanged event! How do we tell this WPF Theme library to load a theme we select from the DropDown? Well, if we take a look at the source code of the ThemeManager class that is in charge of loading Themes for us, you will notice that it defines/registers a Dependency Property called "Theme". What does that mean? It means that we can just add this propery to our root window, and bind it to the drop down selection, and that is it. Each time we change a selection in our Drop down list of available themes, ThemeManager loads that Thema and applieas it to our WPF application. The two lines of XAML that allow us to define our dependency property are listed below:



    ...


Now the last question is: How do we populate the "Available Themes" Drop Down list? We simply bind it to ThemeManager.GetThemes(), like below:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    themes.ItemsSource = ThemeManager.GetThemes();
}

And simply put - that is it, by placing the code above together with WPF.Themes project in your solution you get great set of WPF themes, that you can simply use in your app, but also customize and extend.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Currently rated 5.0 by 1 people

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

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

An interesting migration problem from "Linq to Sql" to "Linq to Entities"

September 15, 2008 07:09 by ndibek

As you might have seen  from few of my previous posts I have been working on the MVC demo implementing Csla.  DAL layer of that demo used the Repository pattern, which is essentially just a wrapper around Linq2Sql DataContext:   

 
Then we would have one implementation of IRepository for each Linq to Sql table / DTO object, like for example SqlCustomerRepository.GetAll(), SqlOrdersRepository.GetAll(), etc.
 
All that each of the GetAll() methods would do is return (this is the implementation in SqlCustomerRepository):
 
 
where _db is an instance of the Linq DataContext.  Hiding DataContext away from our BO and abstracting it away from business layer objects makes it easier to test our business objects.  It makes it easy to replace the SqlCustomerRepository, with TestCustomerRepository that might return hard-coded list of Customers instead.
 
Then we use this inside our business object applying necessary filters - all that the method returns is IQueryable<T> so it makes it easy to use result of GetAll() in another Linq query:
  
 
One problem Rocky noticed in this design is that we are returning Linq generated DTOs.  What if our application needs to migrate to Oracle as a back end, for example.  The only option then is Linq to Entities.  But the type generated by Linq to Entities is different than type generated by Linq to Sql.  Although they might have similar signatures they are different objects.
 
One solution would be t create generic Data Transfer Objects that are neither  Linq to Sql neither Linq to Entities and then "map" the either implementations to these "shared" objects that are instead sent as DTOs.  Problem - one would have to hand code all that stuff.  
 
So for now I decided to give up on Linq to Sql in my demo and migrate it to Linq to entities.  Having 2 different database back ends would not matter in Entity Framework as either Sql Server or Oracle tables are mapped into Entities.  But that meant migrating to Linq to Entities.
 
I thought that this will present not much work at all as the queries are rather simple, and both frameworks support the same Linq syntax.  So I regenerated my Entity diagram using EF.  Everything compiled - good!.  
 
But when I ran the application - I got the following error:
 
Only parameterless constructors and initializers are supported by LINQ to Entities.
 
So although it compiled as perfectly valid Linq Query, at runtime it broke due to the fact that Linq to Entities can not evaluate expression if there are constructors with parameters, or initializers that are not an anonymous objects.  Took me a while to wrapmy head around that statement, but that essentially is what EF team states.  You can check it out in greater detail on following two sites:
 
Essentially Linq2Entities was complaining about:
 
select new OrderInfo(order)
 
part.   OrderInfo is the BO that is part of the list I am trying to populate from EF Entity - order, which is passed as a parameter to its constructor.  So essentially I had to modify the Fetch() method to following:
 
 
 
So what changed?  We are selecting the "order", which is the Linq to Entities object, and then we have to iterate through the list of those objects to map one at the time (as can be seen from use of Add() method instead of AddRange() which was used in Linq to Sql version).
 
Yet another "feature" that any of us migrating from Linq to Sql to Linq to Entities should be aware of.
  
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

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

RhinoMocks 3.5 AAA Model

August 22, 2008 03:58 by ndibek

Ayende has again proven why he is one of the most respectednames in Alt.Net community.  Besides writinga book on language based DSLs, supporting Boo, and NHibernate, having a fulltime job, and writing one of the most informative blog publications, he hasactually practically re-written RhinoMocks in this new version.  And with that RhinoMocks basically takes backthe title of simplest and most productive dynamic mocking framework out there.

Take a look at an ASP.NET MVC test written with RhinoMocks3.3: 

 

As you can see the test above uses a traditional Record& Replay model (referred to as R&P in the rest of this document), wherein Record block we generally set our expectations, and then the Replay block isused to perform actions on object being tested, allowing our Mock objects to execute and verify expectations.

Now let’s take a look at the same test written withRhinoMocks 3.5:

 



This test uses Arrange, Action and Assert model (AAA).  What you will notice first is that there areby far fewer lines needed to setup mocks.

In the AAA version there is no need to instantiateMockRepository, once you generate your Mock, or in this case Stub object, youcan setup your expectations directly on the mock instance. Lines 21 and 22 inR&P version of the test are replaced by single line of code in AAA version –line 22.

You will also notice that we are using GenerateStub()instead of DynamicMock().  Put simply thereis a difference between Mock and Stub objects and RhinoMocks recognizes thatallowing us to write tests that better state their purpose.  For some of you scratching your heads,easiest way to describe the difference is to say that Mock objects are used todefine expectations i.e: In this scenario I expect method A() to be called withsuch and such parameters.  Mocks recordand verify such expectations.  Stubs, onthe other hand have a different purpose: they do not record or verifyexpectations, but rather allow us to “replace” the behavior, state of the “fake”object in order to utilize a test scenario.

In this case the behavior we want to stub is: “WhenGetCustomers() is called return the testCustomers list.”  You can see that AA version uses a Lambda expressionto define the method being called.  Againthe line 24 in AA version replaces lines 24-30 in R&P version.

And lastly at the end of the AAA version, as we have definedour expectation directly on the mock object itself (which replaced the recordblock), there is no need to define the Playback block either.  It is assumed that it follows the recordedassumptions.  Therefore the Playbacksection of the R&P model is comparable to Action and Assert sections of theAA model.

So as you can see our tests have dropped from 13 down to 7lines of code.  Also due to a lot simplermocking portion of the block tests are now lots easier to read and maintain.  I must add that this is only the portion ofthe new features Ayende is adding to RhinoMocks, and for more details I wouldrefer you to go to RhinoMocks wiki as well as Ayende’s blog.  Personally I would like to congratulate himon making a good Dynamic Mocking tool great.

http://ayende.com/Wiki/Default.aspx?Page=Rhino%20Mocks%203.5&AspxAutoDetectCookieSupport=1#WhatsNewinRhinoMocksDF

 

 

 kick it on DotNetKicks.com

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

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

Fluent Stubs

February 7, 2008 05:20 by ndibek

Refactoring has become a common practice amongst many developers I work with.  Why refactor?

Well, first it takes the pressure of off design phase of project in a sense.  You do not have spend ton of time upfront designing the code and assuring that you thought of every detail before you even write a single line of code.  You simply get a rough design and start coding right away, knowing that as you implement the system, get more familiar with the code, you will notice better patterns and refactor the code towards them.

We all know that, if done right, refactoring leads to simpler smaller code base that is easier to maintain.  Meantime we use Unit Tests to assure that the refactoring we performed did not change the outcome or results that our code produces.  I have been following this practice for a while and it has kept me out of trouble.

However what I realized over time is that the Unit Tests themselves become more complex, with too much duplication, and too hard to read.

Take for example this problem I had recently at the client I am working for.  We inherited a “failed” project (story of my life – I always end up coming in to fix someone else’s mess, but enough about that), a project that  another consulting company has given up on after complicating the matter a bit first.

No, they did not use code refactoring, they did not have unit tests, instead they have used code generation tool to “save time”.  It is just that their code generation templates were not really thought through.  Now we have a complex system, with a lot of bugs to clean and lot of code to refactor.  And yes, in order to refactor we had to start writing unit tests to support it.

Well all of their Business Objects are initialized by making a DB call in their constructor that uses Datasets as the DTOs that transfer that data from the DAL (I know what you are going to say now – but sometimes you have to work with what you have – we have to bring this site online!).

But lets start with an example.  Lets say I had a bussiness object called ShoppingCart and that it contained a list Product sand a list of Options for eaach product.  In the constructor of the ShoppingCart, they would have an instance of a ShoppingCartData object that would have a method callled ExecuteDataSet() which although the name does not state it returns all Products and their options that belong to this shopping cart.  Then the code inside of the dataset woule lop through the tables and populate both object lists, something like:

ShoppingCartData _shoppingCartData = new ShoppingCartData();

public ShoppingCart()

{

     DataSet ds = _shoppingCartData.ExecuteDataSet();

     foreach(DataRowView in ds.Tables[0].Rows){

}

So in order to write tests against these objects I had to mock the DAL call and replace the DataSet that the DB would return with my own.   As you can see ShoppingCartData was not injected, nor did it have an interface so for mocking part I had to bring the big guns – TypeMock. 

Mock data = MockManager.Mock(typeof(ShoppingCartData));

cartData.ExpectAndReturn("ExecuteDataSet",cartDataSetStub); 

So mocking the Db call and taking DB out of eqation was easy.  Even generating the stub data for the tests was not the problem.  You might have read one of my previos blogs where I wrote about this little code generation tool that helped me generate DataTable Stub objects just by runnig the sql :

http://www.nermins.net/post/2007/07/Mock-ADONET-with-ease-using-IDataReader-Stub-objects.aspx

In that previous example I take advantage of DataTable CreateReader() method to generate IDataReader Stubs.  However in this case my Stub objects are DataSets, so I can use these table Stubs directly.

I also have the code for that tool available on the google code site:

http://code.google.com/p/data-stub-generator/

So, if setting up mocking and setting up Stub data was not the problem then what was? I had to write a number of tests against each of the BO including Shopping Cart.  That meant setting up the data for the cartTadaSetsTub DataSet.  I also wanted my code genaration tool to generate tables with one and couple of tests records that represent the dafault /valid data, and then explicitly set the values/cells that were needed for the test in the test itself.

For example let’s say that we have the rule that says that shopping cart can not check out if there is at least on item that has been discontinued since we placed it on the shopping cart.  That means that my table returning Products data would have to have one record that has “Discountinued” column set to true.  So let’s take a look at the code needeed for that:

DataSet cartDataSetStub = new DataSet();

DataTable products = new ShoppingCartProductsStub();

products.AddDefaultRow();

products.Rows[0][“Discountinued”] = true;

DataTable options = new ShoppingCartOptionsStub();

cartDataSetStub.Tables.Add(products);

cartDataSetStub.Tables.Add(options);

 

Mock cartData = MockManager.Mock(typeof(ShoppingCartData));

//Assure that _shoppingCartData.ExecuteDataSet()

//returns our cartDataSetStub instead of calling DB

cartData.ExpectAndReturn("ExecuteDataSet",cartDataSetStub); 

ShoppingCart cart = new ShoppingCart(); 

Assert.That(cart.CanCheckOut, Is.EqualTo(false));  

First 7 lines of code are there just to simply setup “fake” output from the database.  There is more code in the part that sets up the data for the test than the actual test.  And actually it could have been worse if I have not used the generated table stub objects ShoppingCartProductsStub and ShoppingCartOptionsStub.  All that code crowds the test and doesn’t really expresss my intention – it is hard to read.  So what did I do to solve that?

Fluent Interfaces to the rescue!  How about this for a change:

Mock cartData = MockManager.Mock(typeof(ShoppingCartData));

cartData.ExpectAndReturn(

    "ExecuteDataSet",

     Stub.GetDataSet(

         ShoppingCartProductsStub.Empty().AddDefaultRow()

            .AtRow(0)

            .InCell(“Discountinued”)

            .SetValue(true),

         ShoppingCartOptionsStub.Empty())); 

 

ShoppingCart cart = new ShoppingCart(); 

Assert.That(cart.CanCheckOut, Is.EqualTo(false)); 

Four statements above are functionaly equivalent to that code mesh in previous example.  And as you can see you can simply read the code to figure what it does!  We are generating DataSet with two tables where on the first table we add the default row of data and then set the cell “Discontinued” to false.  Second table is empty.  And that is it.

So how do these fluent interfaces work?  What is the logic behind them?  Well simply put, lest take a look at the methods that we use to manipulate an object  (StubTable in this case).  In the example above those methods are:  Empty(), AddDefaultRow(), AtRow(int rowNo), InCell(string cellName), SetValue(object value).  Generaly these methods would return void.  In fluent programing they return the object itself or better an interface that implements these other methods.  So first I created the object called StubTable:

public class StubTable : DataTable

{

    private int _currRow = 0;

    private string _currCell = string.Empty;

    protected StubTable(){}

    public static StubTable Empty()

    {

        return new StubTable();

    }

    public StubTable AtRow(int rowNo)

    {

        _currRow = rowNo;

        return this;

    }

    public StubTable InCell(string cellName)

    {

        _currCell = cellName;

        return this;

    }

    public StubTable SetValue(object value)

    {

        Rows[_currRow][_currCell] = value;

        return this;

    }

    public StubTable AddRow(params object[] values)

    {

        Rows.Add(values);

        return this;

    } 

}

  

Then the generated SoppingCartProducts and ShoppingCartOptions DataTables inherit from Stub table and are modified to look like this:

public class ShoppingCartProductsStub : StubTable

{

    public new static ShoppingCartProductsStub Empty()

    {

        return new ShoppingCartProductsStub();

    }

    protected ShoppingCartProductsStub()

    {

        InitColumns();

    }

    private void InitColumns()

    {

        Columns.Add("ShopingCartID", typeof(Int32));

        Columns.Add("ProductID", typeof(Int32));

        Columns.Add("ProductName", typeof(String));

        Columns.Add("ProductNumber", typeof(String));

        Columns.Add("ProductQty", typeof(Int32));

        Columns.Add("Price", typeof(Decimal));

        Columns.Add("PromotionPrice", typeof(Decimal));

        Columns.Add("Discontinued", typeof(Boolean));

       

    }

    public StubTable AddDefaultProduct()

    {

        Rows.Add(705582, 1, "Round Cook-N-Dine Built-in Cook Top", "MO-60", 5,

          decimal.Parse("1200.9400000000000"), decimal.Parse("1200.9400000000000"),false);

        return this;

    }

}

And Finaly Our Stb class that builds and returns the DataSet DTO:

public class Stub

{

    public static DataSet GetDataSet(params DataTable[] tables)

    {

        DataSet ds = new DataSet();

        foreach (DataTable table in tables)

            ds.Tables.Add(table);

        return ds;

    }

} 

The conclusion I would draw from this is that with a little thinking upfront, and a little refactoring we can make our tests a lot more readable.  We always have to keep in mind that our tests might be the first thing that the next developer is going to look at.  Making the test little bit more readible helps them figure out easier on how the actual object being tested is used and what are the expectations set for it.

 

kick it on DotNetKicks.com

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

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

Number of Scaffolding options grows in MVC for ASP.NET

January 20, 2008 06:51 by ndibek

As most of you already know Scott has announced that the Dynamic Data (see screencast) is going to have an MVC compatible version.

It appears that Rob Conery and SubSonic team have worked on MVC compatible version of SubSonic code-named Makai.

As you can see from the screen bellow, they implemented a ScaffoldController<T>, where T is a "model" portion of the MVC.  By inheriting from ScaffoldController<T> and declaring your model class, Makai framework implements all of the Create, Update, Delete, List actions for your controllers and generates dynamic views.  Therefore creating a prototype is a breeze.

I  do understand that a lot of MVC purist do tend to ignore the Scaffolding portion of the MVC, but it is a necessary evil.  MVC is a new technology in .Net world and it is hard to sell it to many IT managers.  But sometimees when they see how rapidly we develop a prototype  they might consider looking further.

Same as dynamic data, Makai generates a set of initial templates, that the list,edit and update views are using.  These templates can be overriden/modified and that is one way for us to get some flexibility in a defining the layout of the views in a prototype.

In addition to that, since Makai implementation is based on the controller, we simply can enrich the functionality by adding the new Actions/Views to our ScaffoldingController class.  This allows us to "evolve" the prototype into the product over time, instead of having to drop all of the prototype and start from scratch.

 For more details on Makai please visit Ron Conery's blog here.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

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

Scott Guthrie announces ASP.NET MVC framework at Alt.Net Conf

October 10, 2007 01:27 by ndibek

I have had several moments in my career where I was near a point of just simply giving up on MS and joining the "other side".  I remember the time few months before .Net 1.0 was released.  Java camp was leading the development world with innovations, while MS kept trying to persuade us that VB/COM was the way to go.  At that time I even joined the Java team at my company almost entirely making a switch.   

Then I was given an opportunity to review technologies for complete replacement of one of the ASP sites, project I was assigned to lead.  I evaluated obviously ASP, JSP, and soon to be released ASP.Net (learning C# at the same time).  And the thing that stroked me then was: "My God, sleeping giant has awaken!"  There was no question in my mind that C#/.Net was not a mere Java clone, but a well thought of framework and language that went one step further.  In addition there was nothing like ASP.NET available on the market.   

We started on the project the week .Net was released.  Completed it month ahead of schedule.  I stayed in MS camp.  

Another moment was just recently.  For any of you that read my blog you will know that I am really big fan of the Agile process and specifically Test Driven Development.  One of the problems with the TDD is being able to write/define tests/behaviors throughout your code including all layers of the application.  And we all know that sometimes UI code can prove virtually untestable.  That is where flavors of MVC/MVP patterns come in.  They help us solve that problem.  

MVC being doable in windows forms (using IoC, and frameworks like CAB), it was nearly impossible to accomplish it in the ASP.NET web development.  

That is when I saw my first demo of Ruby on Rails.  Everything that was missing, or done wrong in ASP.NET was implemented right in Ruby.  No huge configuration files, XML that "generates", code, source code versioning and schema migration are coordinated.  Schema is defined in one place only.  OR Mapping and the ActiveRecord pattern implemented flawlessly.  Ruby uses a true MVC implementation.  And it is all easy to learn and implement.  And productivity gained in developing, maintaining, migrating/updating, deploying these web apps is enormous.  

These concepts have been around for a few years.  Loads of Java folks and already some of the .Net folks are moving into Rails development.  Yet Microsoft stayed quiet about this, having virtually none of these features in upcoming VS2008.   

And right about time I am truly about to give up on MS altogether, I read this post from Jeffrey Palermo about an announcement of the MVC framework Scott Guthrie and his team are working on to be released as an add-on to the VS 2008.  Here are the goals of that project:

·  Natively support TDD model for controllers.

·  Provide ASPX (without viewstate or postbacks) as a view engine

·  Provide a hook for other view engines from MonoRail, etc.

·  Support IoC containers for controller creation and DI on the controllers

·  Provide complete control over URLs and navigation

·  Be pluggable throughout

·  Separation of concerns

·  Integrate nicely within ASP.NET

·  Support static as well as dynamic languages  

 

Folks familiar with MonoRail might say that there is all that built in the MonoRail project and lot more (ActiveRecord, Windsor, etc), and I agree with that.  But having all this come from Microsoft (with all of the visibility that comes with it), can only be a good thing.  I applaud Scott and his team - this is what I and bunch of the folks I know have been waiting for.  And yes, I think I will stay in MS camp for a while now.

 

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

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

An Infragistics WTF

October 2, 2007 10:48 by ndibek

For all of us who have been unlucky to work with Infragistics controls, there comes a time where we say enough is enough! Where do I start?  Their archaic object model is horrible. 

Lets say you are using Ultra(complicated)Grid, and try to set an attribute of a row, or a column, be it width, color something else?  How do you think you would go about doing that?

 

Maybe  UltraGrid has Rows and Columns collections where all the properties related to a specific one can be set?  Not likely!  More likely you will have to go into UltraGrid.DisplayLayout, or maybe UltraGrid.Override. ...  But perhaps it is UltraGrid.Bands[..]...How about all those Appearance objects crowding the designer code and being trully randomly generated? 

That is the type of code that brings Source Control merge down to its knees.  And naturaly in case that 2 developers, God forbid, worked on a same screen containing Infragistics controls - due to the Apearances merger issues, your from designer is going to crash next time you perform "Get Latest". 

 

But that is not the topic I want to discuss today.  The problem is much more simple but yet somehow more irritating.  So I have had a control that inherits from UltraCombo.  Lets call this control NerminsCombo.  I had to define a behavior that happens each time value is selected in the dropdown of Nermin's combo.  So far simple.So I find a protected RowSelected event.  Obviously I am not about to register RowSelected event handler in the control that fires the event.  As we all know all controls have protected methods that are in charge of firing the events and their signature always is On[Event Name].

  

I guess I am lucky because I find the protected OnRowSelected() method right away.  So I override it, calling the base.OnRowSelected() first and then my implementation.  Then I run a quick test, and....   nothing happens.  I put the break point and it does not get hit.  WTF! 

An hour later, and after trying several different options, googling for possible blog entries about a bug in Infragistics, I finally registered an event handler to the RowSelected in the form that was using NerminCombo.  That handler got called but at the same time the code in the OnRowSelected override was executed.So OnRowSelected was only called if there were registered event handlers to RowSelected. 

So obviously this method was not firing the RowSelected event.  Using one of my favorite tools – Reflector, I disassembled the code of the UltraCombo and took a look at it. 

Finally after all this I discovered another protected method called FireRowSelected.  Like its name stated it was the method that was in charge of invoking RowSelected event.  Overriding this method produced desired results – defining a behavior that is executed inside the NerminCombo each time a selection of the row was made.

 

Now comes the question – why would Infragistics not follow control design recommendations from Microsoft?  Does the design of this control pre-dates .Net?  If that is the case, why wouldn’t they note this discrepancy in their help documentation?  And why do I have to waste my time on things like these each time I write code that depends on Infragistics controls?

 

 

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

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

Mock ADO.NET with ease using IDataReader Stub objects

July 10, 2007 11:16 by ndibek

 

Before I start, I would like to point outthat if you are confused about differences between Mock and Stub objects, please readthe Fowler’s post on the subject:

http://www.martinfowler.com/articles/mocksArentStubs.html

I have seen too many “Unit tests” where developersdo not isolate the test to the unit (object/method) being tested.  Yesthey are testing a business object, but to test its behavior they load half of theobject hierarchy in the project.  Moreoverif your object gets initialized from external resource like a database, then theycreate this complex “test databases” that contain their test data.  Thesedatabases have to be shared with other developers.  Ifyou have a continuous build environment that runs tests as a part of the build process,then you have to have a copy of the test database there.  Allthese test databases have to be modified as you modify schema/data in your developmentdatabase.  In addition if your test modifiesdata in the database then you need to setup an additional process in the SetUp orTeardown to restore the data to initial state.

So the test should be simpler if we mock thedb dependency, right?  So what does thatinvolve?  Let’s say we have an objectcalled project Project with constructor as described below:

public Project(IProjectGateway gateway, int id)

{

    using(IDataReader dr= gateway.GetProjectBy(id)) {

        if(dr.Read()){

            _id= dr.GetInt32(0);

            _name= dr.GetString(1);

            _date= dr.GetDateTime(2);                   

        }

    }

}

 

Where IProjectGateway is an interface defininga set of methods/and object in charge of persistence of the Project data to and fromthe database.    Solets look how that interface might look like:

public interface IProjectGateway {

    IDataReader GetProjectBy(int id);

    ...

}

So far this is simple, right?Actual implementation of that interface does not matter for our test.  Why?  Becausewe are not testing database, its resources/file storage, hardware, connection pooling,network connections, etc.  All we aresupposed to test is that our object properly populates its field from a returned DataReader.  

To test the Project object without the databaseroundtrip we will only need to mock the IProjectGateway, setting the expectationsfor the GetProjectBy(id) to return our test data (data reader).  I have to mentionthat the dynamic mocks in the examples bellow were done using my favorite mockingtool TypeMock.Net.

[Test]

public void AssureFetchMapsFields()

{

    Mock<IProjectGateway>projGatewayMock = MockManager.Mock<IProjectGateway>();

 

    projGatewayMock.ExpectAndReturn("GetProjectBy", new ProjectDataStub().CreateDataReader());

   

    Project project= new Project(projGatewayMock.MockedInstance,1);

 

    Assert.AreEqual(1,project.Id);

    Assert.AreEqual("Test",project.Name);

    Assert.AreEqual(DateTime.Parse("1/1/2000"),project.Date);

}

 

So lets see what exactly have we done in thetest above.  First line creates our dynamicmock instance.  Second line is the interestingpart.  It states that we expect one methodcall on our IProjectGatewayMock, and that is “GetProjectBy()” method.  Onceit is called we want the IDataReader to be returned from ProjectDataStub.CreateDataReader().  Therest of the code instantiates the Project object and then assures that the Project’sproperties are initialized.

But what about this ProjectDataStub.CreateDataReader()?  WellI have noticed the ability of the DataTable objects to create an instance of TableDataReader(whichimplements IDataReader).  So theoreticallywe could create a DataTable with column types that reflect the types of the actualcolumns of the table/view we are fetching from db and populate this DataTable withtest record(s).  Then our mock IProjectGatewaycan return the IDataReader from this object, and voila – no db or any other externalconnection used in the test.

So if we follow this logic the ProjectDataStubshould be an object that inherits from DataTable and populates its columns and rowswith test records when it is constructed.  Butcoding these stub object for each and every test might be a bit tedious.  Tosolve this problem I have created a rather simple tool that allows us to generatethis DataStub simply by copying and pasting select SQL statements from the fetch StoredProcedure and executing it.

 

Above is the scren shot showing how tool works and its output.  If you thinkthat this tool might be useful for you feel free to download the code from the linkbellow:

StubGenerator.zip(780.62 KB)

Is this all when it comes to testing the DAL?  No, obviously we have only testedthe data mapping part.  Code in this Project constructor can throw SqlExcpetion(database down, network problem, schema problem).  We need to assure that ourcode handles that.

Now putting the try/ctach block in the Project constructor does not make sense - Ido not want Project instantiated if we were unable to retreive its data.  Sohow do we test this case?  Lets assume that our application is using Model ViewPresenter architecture, and that the object instantiating our Project is the Presenterobject of the View that displays Project.  Obviously we need to assure that thisPresenter can recover from the SqlException thrown by Project.  Lets take a lookat the code bellow:

public class ProjectPresenter

{

....

 

public void DisplayProject(){

    try{

        Projectp = new Project();

 

        ...do something with project like display it on the view etc...

 

    }catch(SqlExceptione){

        Log.LoqException(e);      

    }

}

 

So if we can assure that the Log.LogException(e) is called when the Project throwsthe SqlException, that would be a proof that the exception was handled. Keep in mind that in Test Driven Development we would be writting the test prior tothe DisplayProject() method being written (and the catch block inside of it existing)

Dynamic mocking helps us here also.  In this case we are testing the Presenter,which means that the other two objects Log and Project would be mocked.  Testwould encompass mocking ProjectConstructor instead of returning Project throws SqlException,and then assuring that the Log Mock accepts the call to LogException(e).

In addition there would be tests that we need to run for Insert, Update and Delete(if Project needs to support that), but I will leave that for a future post.

 

 

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Currently rated 5.0 by 1 people

  • Currently 5/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