Introduction

When we create LOB (Line-of-business) applications, we use to develop them in a modular way, to satisfy many requisites:

  • The application is sold by modules – the customer can buy the sales module, but not the industrial one.
  • The application can be developed by separated teams – each team develops an independent module.
  • The modules are only loaded when the user needs it.
  • The application doesn’t need to be completely redeployed when a module changes
  • We can create new modules and add them to the application with no need to change the other modules.

To create a modular application we must create a custom infrastructure that needs lots of work and can introduce bugs to the system

.Net 4.0 brought a new resource that allows us to create modular and extensible applications: MEF (Managed Extensibility Framework). This is a framework to create extensible apps and it is thoroughly tested – Visual Studio uses MEF for its extension system: when you use a Visual Studio add-in, you are using MEF.

Introduction to MEF

Before developing out modular application, we will see how to use MEF. To use it, you must include a reference to System.ComponentModel.Composition. After adding the reference we must tell to the program which are the parts that must be combined: on one side, we have the exported classes, the modules that will be added to the main module, that will fit in the imported parts.

To do this association and the module discovery, combining the exported parts to the imported ones we use Containers. They will discover the modules and will combine the exported to the imported parts. Containers can use catalogs to find the application parts. Does this seem difficult? Let’s see how does it work in the real world.

Create a new console project and add a reference to System.ComponentModel.Composition. Create a new class and call it Menu:

public class Menu
{
    private Module _module;
    public void OptionList()
    {
       Console.WriteLine(_module.Title);
    }
}

We need to create the Module class:

public class Module
{
    public Module()
    {
        Title = "Customers";
    }
    public string Title { get; set; }
}

Now we need to declare what will be exported and where this exported class will fit, using the [Import] and [Export] attributes:

public class Menu
{
    [Import]
    private Module _module;

    public void OptionList()
    {
       Console.WriteLine(_module.Title);
    }
}

[Export]
public class Module
{
    public Module()
    {
        Title = "Customers";
    }
    public string Title { get; set; }
}

Note that the _module field in the Menu class is private – this doesn’t affect the composition. Now, we need to create our container and let it do its magic. In Program.cs put the following code:

static void Main(string[] args)
{
    var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
    var container = new CompositionContainer(catalog);
    var menu = new Menu();
    container.ComposeParts(menu);
    menu.OptionList();
    Console.ReadLine();
}

We have created an AssemblyCatalog (that searches the parts in the assembly – in our case, in the current assembly), then created the container that composes the parts after the menu is created. When the menu.OptionList() method is called, the module’s title is listed:

fig1

Getting more than one component

Now, you will say: but we have only one module listed. How do we do to have more than one? We must create a new interface IModule:

public interface IModule
{
    string Title { get; set; }
}

Our class will implement this interface and the export will tell that we are exporting the IModule interface:

[Export(typeof(IModule))]
public class Module : IModule
{
    public Module()
    {
        Title = "Customers";
    }

    public string Title { get; set; }
}

In order to match the parts, we must say that the imported part is also of IModule type:

public class Menu
{
    [Import]
    private IModule _module;
    public void OptionList()
    {
       Console.WriteLine(_module.Title);
    }
}

We execute the application and see that everything works like before. We can add the new modules:

[Export(typeof(IModule))]
public class Customer : IModule
{
    public Customer()
    {
        Title = "Customers";
    }
    public string Title { get; set; }
}

[Export(typeof(IModule))]
public class Product : IModule
{
    public Product()
    {
        Title = "Products";
    }
    public string Title { get; set; }
}

[Export(typeof(IModule))]
public class Supplier : IModule
{
    public Supplier()
    {
        Title = "Suppliers";
    }
    public string Title { get; set; }
}

We execute the application and… we get a ChangeRejectedException exception:
More than one export was found that matches the constraint: ContractName IntroMEF.IModule“. MEF is complaining that we have many classes that export IModule.

The [Import] attribute allows only one export for the same interface. If there is more than one, this exception is thrown. When we want that many classes export the same interface, we must use the [ImportMany] attribute. To allow importing all the classes, we need to change the import a little, changing the attribute to [ImportMany] and the property type of the _module
field to IEnumerable<IModule>:

public class Menu
{
    [ImportMany]
    private IEnumerable<IModule> _modules;

    public void OptionList()
    {
        foreach (var module in _modules)
        {
           Console.WriteLine(module.Title);
        }
    }
}

We also changed OptionList to list all the modules. Now, when we execute the application, all the modules are found and listed:

fig2

Working with modules in different assemblies

You may be thinking: “this is easy to do – everything is in the same assembly. Doesn’t MEF allow modular and extensible apps?”. All the magic is in the container and in the catalog. We have  reated an AssemblyCatalog pointing to the current assembly, but we could do the same thing pointing to another assembly. You will answer: “this is still easy, I can add a reference to the other assembly where the modules are located. Where is the magic?”.

AssemblyCatalog is not the only catalog that we can use. We can use other catalog types, like the DirectoryCatalog, that finds parts in assemblies located in a specified folder.

Let’s change our project: in the solution, create a Portable Class Library and give it the name of IntroMEF.Interfaces. Choose the desired frameworks (use Framework 4.0 or higher) and delete the Class1.cs file. Add a new interface and put there the IModule interface, removing it from the main project. On the main project, add a reference to the interface project.

Create a new Class library project and give it the name of IntroMef.Modules. Add a reference to System.ComponentModel.Composition and remove the Class1.cs file. Add a
reference to IntroMef.Interfaces and move the classes Customer, Product and Supplier to the new project.

Now we need to tell that our parts are not only in the current assembly, but they can also be found in the current folder. For that we must compose two catalogs: one for the current assembly (for the imported parts) and another for the folder (for the exported parts). We will use an AggregateCatalog to compose both catalogs:

static void Main(string[] args)
{
    var catalog = new AggregateCatalog(
        new AssemblyCatalog(Assembly.GetExecutingAssembly()),
        new DirectoryCatalog("."));
    var container = new CompositionContainer(catalog);
    var menu = new Menu();
    container.ComposeParts(menu);
    menu.OptionList();
    Console.ReadLine();
}

 

We execute our application and nothing happens – no module is listed. That is due to the fact that we haven’t copied the modules assembly to the folder where the executable is located. Copy the assembly IntroMef.Modules to the executable folder, open a command window and execute the application again. Now the modules are recognized.

fig3

We didn’t need to add any references to the main project in the module library nor add a reference to the library in the main project. All we had to do is to copy the file to the executable folder. MEF found the modules when the assembly file was in the correct folder.

Creating a WPF project with MEF

Now you may be thinking: “that’s great, but I don’t create any console projects – how do I do a modular project using WPF?”. The answer is, in the same way we create a console application. To show that I am not lying, we will create a WPF project.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="120" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <ListBox Grid.Column="0" ItemsSource="{Binding Modules}" 
             DisplayMemberPath="Title" x:Name="LbxMenu"/>
    <ContentControl Grid.Column="1" Content="{Binding ElementName=LbxMenu, 
        Path=SelectedItem.Content}" />
</Grid>

We are adding a grid with two columns. In the first one we will add the found modules and in the second one, the contents for the selected module.  To make it work, we must have two properties in every module, Title, with the module’s title and Content, a UserControl with the contents of that module.

We need to create an interface for the modules. We will do in the same way we did before, creating a new library. Create a class library and name it WPFMef.Interfaces. Add the references to PresentationCore and WindowsBase. Remove the Class1.cs file and add a new interface IModule:

public interface IModule
{
    string Title { get; }
    UIElement Content { get; } 
}

Then create a new class library for the modules. Add a new class library and name it WPFMef.Modules. Add the references to WPFMef.Interfaces, System.ComponentModel.Composition, System.Xaml, PresentationCore, PresentationFramework and WindowsBase. Create the exported classes:

[Export(typeof(IModule))]
public class Customer : IModule
{
    public string Title
    {
        get { return "Customers"; }
    }

    public UIElement Content
    {
        get { return new CustomerList(); }
    }
}

[Export(typeof(IModule))]
public class Product : IModule
{
    public string Title
    {
        get { return "Products"; }
    }

    public UIElement Content
    {
        get { return new ProductList(); }
    }
}

[Export(typeof(IModule))]
public class Supplier : IModule
{
    public string Title
    {
        get { return "Suppliers"; }
    }

    public UIElement Content
    {
        get { return new SupplierList(); }
    }
}

The next step is to create the views that will be shown when the option is selected. Create three UserControls with a content similar to this one:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="40" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <TextBlock Text="Customer List" HorizontalAlignment="Center" 
               VerticalAlignment="Center" FontSize="18"/>
    <ListBox x:Name="List" Grid.Row="1"/>
</Grid>

On the constructor of the view, add this code to add items to the ListBox:

public CustomerList()
{
    InitializeComponent();
    List.ItemsSource = Enumerable.Range(1, 100)
        .Select(n => "Customer " + n);
}

We have added a simple window that shows “Customer 1” to “Customer 100”, just to show what can be done. Our module library is finished.

Go back to the main project, add the references to the library WPFMef.Interfaces and to System.ComponentModel.Composition. Create a new class and give it the name of  MainViewModel. We will add there the code to initialize the container and the Modules property:

public class MainViewModel
{
    [ImportMany]
    public IEnumerable<IModule> Modulos { get; set; }

    public MainViewModel()
    {
        var catalog = new AggregateCatalog(
            new AssemblyCatalog(Assembly.GetExecutingAssembly()),
            new DirectoryCatalog("."));
        var container = new CompositionContainer(catalog);
        container.ComposeParts(this);
    }
}

We only need to associate the ViewModel to the View. In MainWindow.xaml.cs, add the following code:

public MainWindow()
{
    InitializeComponent();
    DataContext = new MainViewModel();
}

The project is ready and can be executed. When we execute it, we don’t see anything in the window. We forgot to copy the assembly with the modules again. Just copy the assembly to the executable folder and run the program again. Yesssss!

fig4

The data is shown when we select an option the content view at the right is changed.

If you don’t want to copy the project manually, you can change the project options, changing the output path for the modules, pointing to the executable path:

fig5

Conclusions

As you can see, MEF allows creating modular applications in an easy way that allows expanding our projects just by copying the dlls with the new modules. That works the same way in Windows Forms, WPF, Silverlight, Asp.Net and even Windows 8 (using NuGet). You have a standard way to create plug-ins that are not coupled, allow development done by many teams and adding or fixing modules with no need to recompile the whole project.

The full source code for this article is available in https://github.com/bsonnino/IntroMefEn and https://github.com/bsonnino/WPFMefEn

 

Introduction

In the previous article, “Testing the untestable with Fakes”, I have shown how to create unit tests for the legacy code that didn’t allow tests. With these tests in place we can give a step further to restructuring our code: using best practices on our project, creating code that can be easily maintainable in the future.

In this article we will restructure our code to use the MVVM pattern and Dependency injection. We will use here Unity, a framework created by Microsoft Patterns & Practices, for dependency injection.

Project architecture

Our project had all the code in code-behind and that makes creating tests a difficult task. Besides, that, it had a dependency on DateTime, that makes almost impossible to create reproducible tests.

The first step is to separate the model and the business rules from the view layer. This is done with the MVVM (Model-View-ViewModel) pattern. This pattern separates the presentation layer (View) from the data model (Model) using a binding layer, named ViewModel.

This design pattern makes extensive use of DataBinding in WPF/Silverlight/Windows Phone/Windows 8 and was created on 2005 by John Gossman, a Microsoft Architect on Blend team. If you want more information about this design pattern, you can check Josh Smith’s article on MSDN Magazine,  http://msdn.microsoft.com/en-us/magazine/dd419663.aspx.

The  ViewModel  is a class that implements the INotifyPropertyChanged interface:

public interface INotifyPropertyChanged
{
  event PropertyChangedEventHandler PropertyChanged;
}

It has just one event PropertyChanged that is activated when there is a change in a property. The Data binding mechanism present in WPF (and in other XAML platforms) subscribes this event and updates the view with no program intervention. So, all we need to do is to create a class that implements INotifyPropertyChanged and call this event when there is a change in a property to WPF update the view.

The greatest advantage is that the ViewModel is a normal class and doesn’t have any dependency on the view layer. That way, we don’t need to initialize a window when we test the ViewModel.

Creating the ViewModel

The first step for restructuring the program is to create the ViewModel. It is completely independent from the current project and doesn’t interfere with it.

We will use the same project that we’ve used in the previous article. Create a folder and name it ViewModel. In it, add a new class and name it MainViewModel:

class MainViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] 
        string propertyName = null)
    {
        if (PropertyChanged != null) 
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Note that we’ve used the CallerMemberName attribute, from C# 5.0. It allows that the parameter propertyName from method OnPropertyChanged be filled with the name of the property that has called it, if we leave it blank. That means that if we have a property named TextData and do something like this:

public string TextData
{
    get { return _textData; }
    set
    {
        _textData = value;
        OnPropertyChanged();
    }
}

The compiler will fill the parameter with “TextData”, with no need that we explicitly fill it. This is excellent when we change the name of a property: if we had to pass the name for the OnPropertyChanged method and we forgot to change the parameter name, we would not have the change of the UI. Using the CallerMemberName atribute, this doesn’t happen.

Create a new property TextData, like we did above. Now, let’s create tests for this class. Go back to the test project and create a new class, calling it MainViewModelTests.cs. There, create a new test:

[TestClass]
public class MainViewModelTests
{
    [TestMethod]
    public void CreateMainViewModel_TextDataShouldHaveText()
    {
        var viewModel = new MainViewModel();
        Assert.AreEqual(
          "The current date is 01/01/2013 (Tuesday)", viewModel.TextData);
    }
}

When we execute this test, it doesn’t pass, because we didn’t create any code for assigning TextData.

We must create the code for the test to pass. Create the constructor of the MainViewModel class:

public MainViewModel()
{
    _textData = string.Format("The current date is {0:d} ({0:dddd})", 
       new DateTime(2013,1,1));
}

The test passes. We now refactor the code, creating a GetTextDate method:

public MainViewModel()
{
    _textData = GetTextDate();
}

private static string GetTextDate()
{
    return string.Format("The current date is {0:d} ({0:dddd})", 
      new DateTime(2013,1,1));
}

Our method is only valid for 1/1/2013. We must create another test for the other dates:

[TestMethod]
public void CreateMainViewModel_Date01022013_TextDataShouldHaveText()
{
    var viewModel = new MainViewModel();
    Assert.AreEqual("The current date is 01/02/2013 (Wednesday)", 
      viewModel.TextData);
}

This new test doesn’t pass. We need to go deeper – we need to change our program to retrieve the current date, but our test won’t work anymore (and won’t be reliable, as the date changes every day J), unless we use Fakes again. As we said before, this is not recommended. We need to remove the dependency of DateTime.

According to the book “Beautiful code”,  “all problems in computer science can be solved by another level of indirection”. That’s what we will do, create a level of indirection, an interface IDateTimeProvider, which will provide our dates. Create a folder and name it Interfaces and create a new interface IDateTimeProvider in it:

public interface IDateTimeProvider
{
    DateTime Now { get; } 
}

Implement this interface in the class SystemDateTimeProvider:

public class SystemDateTimeProvider : IDateTimeProvider
{
    public DateTime Now
    {
        get { return DateTime.Now; }
    }
}

We will pass this interface to the ViewModel using the Constructor Injection technique: we pass the interface to the constructor of the class and the interface is responsible for providing the current date. When we want the real data, we use the SystemDateTimeProvider class and when we want to test the code, we use a fake class created only for that.

The constructor of MainViewModel is changed to receive the new interface:

private readonly IDateTimeProvider _dateTimeProvider;

public MainViewModel(IDateTimeProvider dateTimeProvider)
{
    _dateTimeProvider = dateTimeProvider;
    _textData = GetTextDate();
}

With this change, we can alter the code of GetTextDate to use the provider:

private string GetTextDate()
{
    return string.Format("The current date is {0:d} ({0:dddd})", 
      _dateTimeProvider.Now);
}

Our tests need to be changed to pass the provider to the constructor of MainViewModel. We need to create a class that implements the interface and does what we want regarding to the date. In MainViewModelTests create the class FakeDateTimeProvider:

public class FakeDateTimeProvider : IDateTimeProvider
{
    private readonly DateTime _currentDateTime;

    public FakeDateTimeProvider(DateTime currentDateTime)
    {
        _currentDateTime = currentDateTime;
    }

    public DateTime Now
    {
        get { return _currentDateTime; }
    }
}

This class receives in the constructor the date we want as the current date. Now we can change our tests, passing an instance of this class:

[TestMethod]
public void CreateMainViewModel_TextDataShouldHaveText()
{
    IDateTimeProvider provider = new FakeDateTimeProvider(
       new DateTime(2013,1,1));
    var viewModel = new MainViewModel(provider);
    Assert.AreEqual("The current date is 01/01/2013 (Tuesday)", 
       viewModel.TextData);
}

[TestMethod]
public void CreateMainViewModel_Date01022013_TextDataShouldHaveText()
{
    IDateTimeProvider provider = new FakeDateTimeProvider(
       new DateTime(2013, 1, 2));
    var viewModel = new MainViewModel(provider);
    Assert.AreEqual("The current date is 01/02/2013 (Wednesday)",
       viewModel.TextData);
}

Our tests pass with no problems and we have removed the dependency to DateTime. The next step is to bind the ViewModel to the View. This is done setting the DataContext property of the view to an instance of the viewmodel. One way to do that is to put the following code on the constructor of the view:

public MainWindow()
{
    InitializeComponent();
    IDateTimeProvider provider = new SystemDateTimeProvider();
    DataContext = new MainViewModel(provider);
}

This works fine, but it has two problems:

  • We have to create an instance of SystemDateTimeProvider to pass it to the constructor of the viewmodel.
  • The viewmodel doesn’t work at design time, thus making it difficult to design the UI.

To overcome these two problems, we will use the ViewModelLocator technique, a class that will use Dependency Injection to locate and instantiate our viewmodels. We will use a Dependency injection framework to do it. There are many good ones in the market, most of them free: Castle Windsor, Autofac, StructureMap and Ninject are very good, but we will use Unity, a framework created by Microsoft Patterns and Practices.

We can install it using Nuget. On the solution Explorer, right-click the References node and choose “Manage Nuget Packages”. Search for Unity and install it:

Unity works in the following way: we register the interfaces with the associated concrete classes in the container and then we call the Resolve method to return the classes instances – all dependencies are resolved and the class instance is returned. There is no need to register the concrete classes if Unity can create them (by having a default parameterless constructor or with dependencies that can be resolved).

For example, the register phase in our classes would be:

_container = new UnityContainer();
_container.RegisterType<IDateTimeProvider, SystemDateTimeProvider>();

To get an instance of MainViewModel, we use something like:

_container.Resolve<MainViewModel>();

We do not need to register the MainViewModel class, because Unity can resolve all dependencies with the registered interfaces. Now, we can create a new class on the folder ViewModel, named ViewModelLocator:

private readonly UnityContainer _container;

public ViewModelLocator()
{
    _container = new UnityContainer();
    _container.RegisterType<IDateTimeProvider, SystemDateTimeProvider>();
}

public MainViewModel Main
{
    get { return _container.Resolve<MainViewModel>(); }
}

We register the IDateTimeProvider interface, associating it to the SystemDateTimeProvider class and create a property named Main that returns an instance of MainViewModel. To use this class, we add an instance to the Resources section of App.xaml. In App.xaml, add this code:

<Application.Resources>
     <viewModel:ViewModelLocator x:Key="Locator"/>
</Application.Resources>

Add the namespace for the ViewModelLocator in the Application class declaration:

<Application 
    x:Class="FakesTest.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:viewModel="clr-namespace:FakesTest.ViewModel"
    StartupUri="MainWindow.xaml">

Finally, in MainWindow, set the property DataContext to the property Main of the ViewModelLocator and bind the property Text of the TextBlock to the property TextData of the ViewModel:

<Window x:Class="FakesTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{Binding Source={StaticResource Locator}, Path=Main}">
    <Grid>
        <TextBlock x:Name="TxtDate" Text="{Binding TextData}"/>
    </Grid>
</Window>

When we do that, the current date data appears at design time:

We can then remove the code behind and our code in MainWindow.xaml.cs stays like that:

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
    }
}

Execute the program and observe that it behaves exactly in the same way as it did before. When we execute our tests, we see that they pass, but the first test (the one we’ve created in the prior article) doesn’t pass:

Test method FakesTest.Tests.MainWindowTests.CreateWindow_TextBlockHasCurrentDate threw exception: 
System.Windows.Markup.XamlParseException: 'Provide value on 'System.Windows.StaticResourceExtension' threw an exception.' Line number '5' and line position '9'. ---> System.Exception: Cannot find resource named 'Locator'. Resource names are case sensitive.

This is due to the fact that we have the dependency between the View and the ViewModelLocator. As we wanted to remove the dependency of Fakes, we can ignore this test, adding the Ignore attribute (we could remove this test, as it doesn’t make sense anymore, but I decided to leave it, as a reminder of the old times that should never come back J):

[Ignore]
[TestMethod]
public void CreateWindow_TextBlockHasCurrentDate()
{
    using (ShimsContext.Create())
    {
        ShimDateTime.NowGet = () => new DateTime(2013,1,1);
        var window = new MainWindow();
        var mainGrid = (Grid)window.Content;
        var textBlock = (TextBlock) mainGrid.Children[0];
        Assert.AreEqual("The current date is 01/01/2013 (Tuesday)",
           textBlock.Text);
    }
}

Conclusions

We finished our restructuring. Our code, once dependent of the Window and to DateTime, making it almost impossible to test, is now detached and 100% testable.

For that, we restructured the code using a ViewModel and Dependency Injection that resolves our dependencies in an automatic way, giving us a bonus of having the data at design time. We don’t need to use Fakes anymore and the program is ready for new updates.

 

Introduction

Sometimes you must do some changes on legacy programs that were not built using good development practices. At that time, our first reaction is to run away from that: the probability of having problems is too high and touching the source code is almost impossible – we are working on a castle of cards, where even the slightest move can bring everything down.

The idea of refactoring (or even rewrite) the code comes from a long time, but where is the time to do that? All projects are late and that’s not a priority, its working, no? Why touch on that?

We can make the situation a little better by creating unit tests for the changes we must do, but how to do that? The program is full of dependencies, the business rules are mixed with the views, and the methods are long and complicated.

The best we could do are integration tests, that are difficult to implement and slow to execute, they will be abandoned very soon. What to do now? The solution is at hand, Microsoft implemented a Microsoft Research’s project, named Moles, and put it in Visual Studio 2012 with the name of Fakes, so we can create test for anything, including .Net Framework classes.

With Fakes we can create unit tests that run fast and don’t depend of anything, nor operating system, machine or database. Here I must do a note: although Fakes can test almost anything, that’s not an excuse to relax our coding style – you must use good programming practices on the new code and do not rely on Fakes to simulate dependencies that should not exist. When you are creating new code, try to do it in a way that you don’t need Fakes, use it only where that is really needed.

The problem

To show how to use Fakes, we will create a small WPF project that has a window with a TextBlock:

 <Window x:Class="FakesTest.MainWindow"  
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
     Title="MainWindow" Height="350" Width="525">  
   <Grid>  
     <TextBlock x:Name="TxtDate"/>  
   </Grid>  
 </Window>  

When the window is initialized, the TextBlock is fed with the current date:

 public partial class MainWindow  
 {  
   public MainWindow()  
   {  
     InitializeComponent();  
     TxtDate.Text = string.Format(  
      "The current date is {0:d}", DateTime.Now);  
   }  
 }  

We should change this code to put the weekday in the TextBlock, like in “The current date is 8/2/2013 (Friday)”. We want to use best practices and will create unit tests for the project. But how to do it? The code is mixed with the View and has a dependency on DateTime, a .Net Framework class.

Creating the test project

The first step is to create the test project. On the Solution Explorer, select the solution and right click it, selecting Add/New Project. Select Test/Unit Test Project and call it FakesTest.Tests. Add to it a reference to our project. Rename the UnitTest1.cs class to MainWindowTests.cs.

Here starts our problem: we want to test what is being shown in the TextBlock. For that, we must create a window, initialize it and look at its content. Not an easy task to do with unit tests.

 Here comes Fakes to rescue. On the test project, on the references, select the reference to the main project and select Add Fakes Assembly. A new reference to FakesTest.Fakes is added – this reference will create all fakes for the window and its componentes. To use it on our tests, we must add the references to System.Xaml, PresentationCore, PresentationFramework and WindowsBase.

 The next step is to create a fake for the DateTime class. Select the System assembly in the references and right click it, selecting Add Fakes Assembly. Now that we have all our environment “virtualized”, we can start creating tests.

To use the components created by Fakes we must surround the calls in a context, with the keyword Using, using a ShimsContext:

 using (ShimsContext.Create())  
 {  
   ….  
 }  

Inside the context, we must tell the behavior of the fake DateTime class, when the method Now will be called:

 ShimDateTime.NowGet = () => new DateTime(2013,1,1);  

To access the DateTime class created by Fakes, we must use the ShimDateTime class. The line above tells us that when the getter of the Now property is called (NowGet), it must return 1/1/2013. From now on, the test becomes exactly the same as any other unit test:

 [TestMethod]  
 public void CreateWindow_TextBlockHasCurrentDate()  
 {  
   using (ShimsContext.Create())  
   {  
     ShimDateTime.NowGet = () => new DateTime(2013,1,1);  
     var window = new MainWindow();  
     var mainGrid = (Grid)window.Content;  
     var textBlock = (TextBlock) mainGrid.Children[0];  
     Assert.AreEqual("The current date is 01/01/2013",textBlock.Text);  
   }  
 }  

We have created the window and verified if the TextBlock has the date we have passed on the fake. When we execute the tests with Ctrl+R+T, we see that the test passes. We are covered here, and we can make the changes we need on our code.

Changing the program

As we already have the test, we can change it for the new feature we want:

 [TestMethod]  
 public void CreateWindow_TextBlockHasCurrentDate()  
 {  
   using (ShimsContext.Create())  
   {  
     ShimDateTime.NowGet = () => new DateTime(2013,1,1);  
     var window = new MainWindow();  
     var mainGrid = (Grid)window.Content;  
     var textBlock = (TextBlock) mainGrid.Children[0];  
     Assert.AreEqual(  
      "The current date is 01/01/2013 (Tuesday)",textBlock.Text);  
   }  
 }  

We have made the change on the test but not on the code. If we run our test now, it will fail:

 Assert.AreEqual failed. Expected:<The current date is 01/01/2013 (Tuesday)>. Actual:< The current date is 01/01/2013>.  

We must change the code:

 public MainWindow()  
 {  
   InitializeComponent();  
   TxtDate.Text = string.Format(  
    "The current date is {0:d} ({0:dddd})", DateTime.Now);  
 }  

When we execute the test, it passes – our change is complete and working. To complete the Red-Green-Refactor cycle from TDD, we can refactor the code, extracting the function from where we set the TextBlock:

 public MainWindow()  
 {  
   InitializeComponent();  
   TxtDate.Text = GetTextDate();  
 }  
 private static string GetTextDate()  
 {  
   return string.Format(  
    "The current date is {0:d} ({0:dddd})", DateTime.Now);  
 }  

We run the tests and they still pass. The change is finished.

Conclusions

As we can see, Fakes helps a lot when we have legacy code that, for its dependencies, don’t allow creating unit tests in an easy way. What we have done here is to simulate the creation of a window and assign a value to a TextBlock, passing the current date with no special arrangement.

We are not advocating using this resource always – you should use Fakes only as the last resource, when the code is already there and there is not an easy way to break it. It can be used as a starting point for the real refactoring of the program: in this case, we must remove the window dependencies using the MVVM pattern and also from the System.DateTime, using some kind of wrapper interface (that we could call as IDateTimeProvider), but this is a subject for another article!