Category Archives: Tools

Leveraging expression trees to unit test ViewModel classes

Introduction: In this article, I’m describing a technique which leverage the expression trees of C# 3.0 in order to facilitate the unit testing of ViewModel’s properties. My final goal is to be able to unit test a ViewModel property in 1 line.

Without any doubt MVVM is now the most used framework to leverage WPF and Silverlight functionalities in the best way ! During the last Mix, 3 sessions were dedicated to this methodology (you can watch the videos online here).

As you already know one of the key advantage of the MVVM methodology is to improve the testability of the overall application by reducing the amount of code in the code-behind and producing ViewModel classes which are testable. We use to say that ViewModel classes are testable because:

  • they are not coupled to UI concepts (controls, focus, keyboard input…)
  • they can wrap model objects using interfaces (for instance a PersonViewModel wraps a IPerson object)
  • they are not subclassing a UI control (such as Button or Window)

Today I’d like to share a technique I’m using to facilitate the unit tests of some properties of my ViewModel classes.

Let’s use a very simple ViewModel class as example:

public class PersonViewModel : ViewModelBase
{
  private IPerson person;
  private bool isSelected;

  public string Name 
  {
     get
     {
        return this.person.Name;
     }
     set
     {
        this.person.Name = value;
        this.OnPropertyChanged("Name");
     }
  }

  public bool IsSelected
  {
    get
    {
      return this.isSelected;
    }
    set
    {
      this.isSelected = value;
      this.OnPropertyChanged("IsSelected");
    }
  }

  // rest of the code omitted for simplicity
}

The Name property, as usually with the MVVM pattern gets its value from the wrapped model object. The easiest way to unit test this property is to use a mocking library. Here is a example using MOQ (my favourite mocking library):

[Test]
public void TestName()
{
  var mockPerson = new Mock();
  
  var vm = new PersonViewModel(mockPerson.Object);

  vm.Name = "Jeremy";

  // verify that the Name property of the IPerson interface has been set
  mockPerson.VerifySet(p => p.Name = "Jeremy");
}

The Selected property is different because it doesn’t wrap a model property. It’s an information that is added to the ViewModel layer in order to control a UI-related property (for example the IsSelected property of a ListBoxItem). This technique is heavily used to have ViewModel classes interact with the WPF or Silverlight TreeView or ListBox control (you can check out this excellent article of Josh Smith for more detail).

In order to unit test this property, we must:
1/ ensure the PropertyChanged event of the INotifyPropertyChanged is raised properly
2/ ensure we can write a value and read back the correct value

Here is a sample code which does this unit test:

[Test]
public void TestName()
{
var vm = new  PersonViewModel();
bool propertyChanged = false;

vm.PropertyChanged += (s, e) => propertyChanged = e.PropertyName ==  "Name";
vm.Name = "newName";

Assert.IsTrue(propertyChanged);
Assert.AreEqual("newName", vm.Name);
}

It quickly become cumbersome to copy/paste this unit test for all the ViewModel properties we have. That’s the reason I started thinking about another way to do it…

Here is the feature I’m proposing:

[Test]
public void TestName()
{
var vm = new PersonViewModel();
TestHelper.TestProperty(vm, v => v.IsSelected);
}

In this sample, I’m telling I want to test the IsSelected property of the PersonViewModel type. The advantages are:
1/ less code involved : 1 line to test 1 property
2/ intellisense support in order to prevent typing error and no more “magic” string to give the name of the property
3/ refactoring the name of the property will refactor this sample code too
4/ automatic generation of default test values behind the scene

How does it works ?

  • TestProperty treats the second parameter as an Expression<Func> and not as a Func directly
  • Using expression tree (the “v => v.IsSelected” part),  I’m able to retrieve the name of the property and its type
  • Using reflection, I’m able to get and set the value
  • Depending on the type of the property (string, bool, int, double), I have default values write and read back (with a test to ensure that the PropertyChanged event has been raised properly).

Here is the code of the TestPropertyMethod:

public static void TestProperty(T viewmodel, Expression> expression)
    where T : INotifyPropertyChanged
{
    if(expression.Body is MemberExpression)
    {
        MemberExpression memberExpression = (MemberExpression) expression.Body;

        if (expression.Body.Type == typeof(bool))
        {
            TestViewModelProperty(viewmodel, memberExpression.Member.Name, true, false);
        }
        else if (expression.Body.Type == typeof(string))
        {
            TestViewModelProperty(viewmodel, memberExpression.Member.Name, "value1", "value2");
        } 
        else if (expression.Body.Type == typeof(int))
        {
            TestViewModelProperty(viewmodel, memberExpression.Member.Name, 1, 99);
        }
        else if (expression.Body.Type == typeof(double))
        {
            TestViewModelProperty(viewmodel, memberExpression.Member.Name, 1.0, 99.0);
        }
        else
        {
            throw new NotSupportedException("Type is not supported");
        }
   }
}

And the TestViewModelProperty:

private static void TestViewModelProperty(T viewModel, string propertyName, U value1, U value2)
    where T : INotifyPropertyChanged
{
    bool propertyChanged;
    viewModel.PropertyChanged += (s, e) => propertyChanged = e.PropertyName == propertyName;

    propertyChanged = false;
    viewModel.SetValue(propertyName, value1);
    Assert.IsTrue(propertyChanged);
    Assert.IsTrue(viewModel.GetValue(propertyName).Equals(value1));

    propertyChanged = false;
    viewModel.SetValue(propertyName, value2);
    Assert.IsTrue(propertyChanged);
    Assert.IsTrue(viewModel.GetValue(propertyName).Equals(value2));
}

I’m using 2 extensions methods in order to get and set value from the ViewModel object using reflection. Here they are:

private static T GetValue(this object obj, string propertyName)
{
    var propertyInfo = obj.GetType().GetProperty(propertyName);
    return (T)propertyInfo.GetValue(obj, null);
}

private static void SetValue(this object obj, string propertyName, T value)
{
    var propertyInfo = obj.GetType().GetProperty(propertyName);
    propertyInfo.SetValue(obj, value, null);
}

Please feel free to download the source code of the ViewModelTestHelper class.

Mix10: Windows Phone 7 series development tools available

The first keynote of Mix10 is just over and the biggest announcement I was waiting for occured: Windows Phone 7 series development tools are NOW available for FREE.

Grab the tools right now ! You’ll need:

If you want more details about Blend4, you can check out Christian Schormann’s overview. A new website is now live for all Windows Phone 7 series related development information at http://developer.windowsphone.com/

Another announcements is the availability of Silverlight 4 RC and support for VS2010 RC:

For more information about Silverlight 4 RC, you can check out the blog post of Tim Heuer.

I can’t wait to play with all this new stuff. It’s very impressive to see the work done around Windows Phone 7 series. WPF and Silverlight developers just became Windows Phone developer today, and I think this is great !

I’ll give more feedback as soon as the tools will be installed 🙂

Using Reflector to debug a .Net app in Visual Studio without the original source code

Many .Net developers use to say “if you’re a serious developer, then you MUST Reflector”.

I would like to add another statement: “if you want to have an insight and powerful look at how things works internally, use Reflector Professional”.

Last Wednesday, RedGate released a new version of Reflector. You’re probably going to download it soon or later because your actual version is going to expire. When you’ll download the free version, you’ll automatically get a trial (14 days) of the professional edition. Nice, but what’s so special about this edition ?

Let’s see a demonstration of what can be done using Reflector Pro. The following is not an ad for RedGate, I’m just totally amazed by their new feature 🙂

1. Reflector is now integrated into Visual Studio (2005, 2008 and 2010 RC):

2. Select the “Choose Assemblie to Debug…” option to select .Net assemblies for which you don’t have the source code. In this example, I’m using one of the Blend3’s assemblies:

3. Once the process is completed, select the “Explore Decompiled Assemblies” option:

4. Browse to your target assembly and select an interesting type:

5. Put a breakpoint in the code, like you do every day when you debug an app:

6. Run the executable

7. Debug Blend3’s source code ! Use breakpoints, step into methods, inspect variables…

And that’s it. With Reflector Professional, you can:

  • Decompile third-party assemblies from within Visual Studio
  • Step through decompiled assemblies and use all the debugging techniques you would use on your own code. This is incredibly powerful as we saw by debugging Blend3″s source code !

Reflector Professional is available for about 195$ on RedGate website