Enabling buttons in Silverlight and WPF using MVVM and ValidatesOnExceptions

In a previous post we saw how exceptions could be used for Silverlight validation.

While could validate the users input using exceptions, it wasn’t possible to disable the calculate button if the input values were invalid (because they were either blank or non-numeric).

The code used in this post can be downloaded here.

So how are we going to solve the problem?

Throughout the Silverlight refactoring series I’ve tried to illustrate how important SOLID design principles are for having testable applications.

So if we think about the ViewModel, we need to ask ourselves if it’s the right place or should be responsible for validation?

In this case I would say no.

When should the button be enabled?

For a calculate button to be enabled, both text boxes must contain numeric values

This means we have to know if both text boxes are valid at the same time. Taking a step back here, let’s think about the bigger picture.

What if there are three or four text boxes?

What we really after is a class that will be responsible for knowing if any text boxes are invalid.

This can be done by using a validation base class.

In the code below notice how the ValidationBase class doesn’t know anything about enabling or disabling the calculate button.

public class ValidationBase
{
    public readonly Dictionary<string, string> Errors;

    public ValidationBase()
    {
        Errors = new Dictionary<string, string>();
    }

    public void AddError(string propertyName, string message)
    {
        if (!Errors.ContainsKey(propertyName))
        {
            Errors[propertyName] = message;
        }
    }

    public void RemoveErrors(string propertyName)
    {
        Errors.Remove(propertyName);
    }

    public bool IsPropertyValid(string propertyName)
    {
        return !Errors.ContainsKey(propertyName);
    }

    public string GetErrorMessageForProperty(string propertyName)
    {
        string message;
        Errors.TryGetValue(propertyName, out message);
        return message;
    }

    public bool IsValid()
    {
        return Errors.Count == 0;
    }
}

The code below shows the unit tests for the ValidationBase class.

[TestFixture]
public class When_using_the_ValidatiorBase
{
    private ValidationBase _validationBase;

    [SetUp]
    public void SetUp()
    {
        _validationBase = new ValidationBase();
    }

    [Test]
    public void IsValid_should_return_false_when_errors_exist()
    {
        // Arrange
        _validationBase.AddError("propertyName", "message");

        // Act
        var result = _validationBase.IsValid();

        // Assert
        result.ShouldBeFalse();
    }

    [Test]
    public void IsValid_should_return_true_when_no_errors_exist()
    {
        // Arrange
        // collection will be empty at this point

        // Act
        var result = _validationBase.IsValid();

        // Assert
        result.ShouldBeTrue();
    }

    [Test]
    public void IsPropertyValid_should_return_false_if_error_exists()
    {
        // Arrange
        _validationBase.AddError("propertyName", "message");

        // Act
        var result = _validationBase.IsPropertyValid("propertyName");

        // Assert
        result.ShouldBeFalse();
    }

    [Test]
    public void IsPropertyValid_should_return_true_if_error_does_not_exist()
    {
        // Arrange
        // collection will be empty at this point

        // Act
        var result = _validationBase.IsPropertyValid("X");

        // Assert
        result.ShouldBeTrue();
    }

    [Test]
    public void Should_be_able_to_return_message_for_error()
    {
        // Arrange
        _validationBase.AddError("propertyName", "message");

        // Act
        var result = _validationBase.GetErrorMessageForProperty("propertyName");

        // Assert
        result.ShouldEqual("message");
    }

    [Test]
    public void Should_return_null_if_message_does_not_exist_for_error()
    {
        // Arrange
        // collection will be empty at this point

        // Act
        var result = _validationBase.GetErrorMessageForProperty("propertyName");

        // Assert
        result.ShouldBeNull();
    }
}

Validating the users input

There are three outcomes when validating what the user has entered:

  • The value is blank
  • The value is not a number
  • The value is a number

All the ViewModel wants to know is if the users input is valid, choosing the appropriate error message isn’t its concern. This means we need a class that will be responsible for validation and returning the relevant message.

For this we will use the CalculatorValidator class we created in the ‘Applying the Open Closed Principle in Silverlight and WPF using MEF‘ post.

[Export(typeof(ICalculatorValidator))]
public class CalculatorValidator : ValidationBase, ICalculatorValidator
{
    [ImportMany]
    public IEnumerable<ICalculatorValidationRule> CalculatorValidationRules { get; set; }

    public void ValidateNumber(string propertyName, string value)
    {
        RemoveErrors(propertyName);

        foreach (var calculatorValidationRule in CalculatorValidationRules)
        {
            if (!calculatorValidationRule.IsValid(value))
            {
                AddError(propertyName, calculatorValidationRule.ErrorMessage);
                return;
            }
        }
    }
}

This is useful because if we decide to change how to validate the user’s input neither the CalculatorValidator or the ViewModel classes need to be modified.

Hooking it all up

To use the CalculatorValidator in the ViewModel it has to be injected/imported.

[ImportingConstructor]
public CalculatorViewModel(ICalculator calculator, ICalculatorValidator calculatorValidator)
{
    _calculator = calculator;
    _calculatorValidator = calculatorValidator;
    ...
}

Each time a user enters a value in the text boxes the CheckIfNumberIsValid method checks if the calculate button should be enabled and throws an exception if the users value is not valid.

public string FirstValue
{
    get { return _firstValue; }
    set
    {
        CheckIfNumberIsValid("FirstValue", out _firstValue, value);
    }
}

public string SecondValue
{
    get { return _secondValue; }
    set
    {
        CheckIfNumberIsValid("SecondValue", out _secondValue, value);
    }
}

public void CheckIfNumberIsValid(string propertyName, out string propertyValue, string value)
{
    _calculatorValidator.ValidateNumber(propertyName, value);

    CheckIfCalculteButtonShouldBeEnabled();

    if (_calculatorValidator.IsPropertyValid(propertyName))
    {
        propertyValue = value;
        OnPropertyChanged(propertyName);
    }
    else
    {
        throw new Exception(_calculatorValidator.GetErrorMessageForProperty(propertyName));
    }
}

public void CheckIfCalculteButtonShouldBeEnabled()
{
    _calculateCommand.IsEnabled = _calculatorValidator.IsValid();
}

Unit testing the ViewModel in MVVM

By using Moq we can unit test the ViewModel to ensure the button is enabled when there are no validation errors and not enabled when there are validation errors.

[TestFixture]
public class When_using_the_CalculatorViewModel
{
    private Mock<ICalculator> _calculator;
    private Mock<ICalculatorValidator> _calculatorValidator;
    private CalculatorViewModel _calculatorViewModel;

    [SetUp]
    public void SetUp()
    {
        _calculator = new Mock<ICalculator>();
        _calculatorValidator = new Mock<ICalculatorValidator>();
        _calculatorViewModel = new CalculatorViewModel(_calculator.Object, _calculatorValidator.Object);
    }

    [Test]
    public void Initial_value_of_first_number_is_0()
    {
        // Arrange
        // checking initial value

        // Act
        var result = _calculatorViewModel.FirstValue;

        // Assert
        result.ShouldEqual("0");
    }

    [Test]
    public void Initial_value_of_second_number_is_0()
    {
        // Arrange
        // checking initial value

        // Act
        var result = _calculatorViewModel.SecondValue;

        // Assert
        result.ShouldEqual("0");
    }

    [Test]
    public void Initial_value_of_calculate_button_is_enabled()
    {
        // Arrange
        // checking initial value

        // Act
        var result = _calculatorViewModel.CalculateCommand.IsEnabled;

        // Assert
        result.ShouldBeTrue();
    }

    [Test]
    [ExpectedException(typeof(Exception))]
    public void Will_throw_exception_if_input_is_invalid()
    {
        // Arrange
        string propertyValue;
        _calculatorValidator.Setup(c => c.IsPropertyValid("X")).Throws(new Exception());

        // Act
        _calculatorViewModel.CheckIfNumberIsValid("X", out propertyValue, "X");

        // Assert
        // should throw exception
    }

    [Test]
    public void Will_set_property_value_if_input_is_valid()
    {
        // Arrange
        string propertyValue;
        _calculatorValidator.Setup(c => c.IsPropertyValid("X")).Returns(true);

        // Act
        _calculatorViewModel.CheckIfNumberIsValid("X", out propertyValue, "11");

        // Assert
        propertyValue.ShouldEqual("11");

    }

    [Test]
    public void Calculate_command_should_not_be_enabled_if_ViewModel_is_not_valid()
    {
        // Arrange
        _calculatorValidator.Setup(c => c.IsValid()).Returns(false);

        // Act
        _calculatorViewModel.CheckIfCalculteButtonShouldBeEnabled();

        // Assert
        _calculatorViewModel.CalculateCommand.IsEnabled.ShouldBeFalse();
    }

    [Test]
    public void Calculate_command_should_be_enabled_if_ViewModel_is_valid()
    {
        // Arrange
        _calculatorValidator.Setup(c => c.IsValid()).Returns(true);

        // Act
        _calculatorViewModel.CheckIfCalculteButtonShouldBeEnabled();

        // Assert
        _calculatorViewModel.CalculateCommand.IsEnabled.ShouldBeTrue();
    }
}

So what have we achieved?

By using a validation base class we are able to store validation errors and can determine if the controls on the page are all valid.

The ViewModel can take advantage of this functionality and use it to enable and disable the calculate button.

Using exceptions for validation isn’t every developers cup of tea, so be sure to keep an eye on the Silverlight refactoring series to see other approaches we can take to do validation in Silverlight 4.

How to Apply the Single Responsibility Principle to View Models in Silverlight and WPF

When you’re using the MVVM pattern with WPF or Silverlight it’s very easy to a have ViewModels that do too much.

In this part of the Silverlight Refactoring series we will convert a ViewModel with multiple responsibilities so that it adheres to the Single Responsibility Principle (SRP).

The code used in this post can be downloaded here.

Why should you care?

Currently the ViewModel looks like this

using System;
using System.ComponentModel;
using System.Windows.Input;

namespace SilverlightCalculator
{
    public class CalculatorViewModel : INotifyPropertyChanged
    {
        private string _firstValue;
        private string _secondValue;
        private string _result;

        private readonly ICommand _calculateCommand;       

        public event PropertyChangedEventHandler PropertyChanged;

        public CalculatorViewModel()
        {
            _calculateCommand = new RelayCommand(Calculate){IsEnabled = true};
        }

        public void Calculate()
        {
            Result = (Convert.ToInt32(FirstValue) + Convert.ToInt32(SecondValue)).ToString();
        }

        public string FirstValue
        {
            get { return _firstValue; }
            set
            {
                _firstValue = value;
                OnPropertyChanged("FirstValue");
            }
        }

        public string SecondValue
        {
            get { return _secondValue; }
            set
            {
                _secondValue = value;
                OnPropertyChanged("SecondValue");
            }
        }

        public string Result
        {
            get { return _result; }
            private set
            {
                _result = value;
                OnPropertyChanged("Result");
            }
        }

        public ICommand CalculateCommand
        {
            get { return _calculateCommand; }
        }

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

As you can see the logic to add two numbers is in the Calculate method of the ViewModel.

Therefore the ViewModel is responsible for calculating two numbers.

A ViewModel without separation of concerns is difficult to test, maintain and contains code you can’t reuse.

Although we’re only adding two numbers here, brushing the issue under the carpet will have consequences later down the line.

For example in addition to adding numbers what if another developer was given the task of storing the result in a database.

If the ViewModel was as it is now, with no separation of concerns, there is a chance they would put the code to store the value in the calculate method like this

public void Calculate()
{
    // Calculate result
    Result = (Convert.ToInt32(FirstValue) + Convert.ToInt32(SecondValue)).ToString();

    // Store value in database
    DatabaseConnection connection = new DatabaseConnection();
    DatabaseCommand command = new DatabaseCommand("TSQL TO STORE RESULT", connection);
    command.ExecuteNonQuery();
}

Now the ViewModel would be responsible for two things. Next it would be three and this would continue until someone decides to separate the concerns or it gets to a stage where it’s impossible to work with let alone read.

Refactoring the ViewModel to follow the single responsibility principle

Let’s start by creating a class for calculating numbers.

public class Calculator
{
    public int Add(int firstValue, int secondValue)
    {
        return firstValue + secondValue;
    }
}

Notice how the parameters passed to the method are integers, the calculator doesn’t accept string values.

What we are saying here is while it’s acceptable for the ViewModel to use strings for storing numbers the domain layer (or business logic if you prefer) does not.

In other words the add method does nothing more than add two numbers together. Validation should be handled elsewhere.

This makes the unit tests for the calculator very easy to write

[TestFixture]
public class When_calculating_numbers
{
    [Test]
    public void Should_be_able_to_add_two_numbers_together()
    {
        // Arrange
        Calculator calculator = new Calculator(); 

        // Act
        var result = calculator.Add(5, 5);

        //Assert
        Assert.That(result, Is.EqualTo(10));
    }
}

The code below shows how the ViewModel could create an instance of the Calculator class and call the Add Method. Notice how I say could and not should. We’ll see why later in the series.

public void Calculate()
{
    Calculator calculator = new Calculator();
    Result = calculator.Add(Convert.ToInt32(FirstValue), Convert.ToInt32(SecondValue)).ToString();
}

So what have we achieved?

As good boy scouts we have ‘left the ViewModel cleaner than we found it’.

By following the single responsibility principle we have created a ViewModel which is a better canvas for other developers to work with.

If you have arrived here from a search engine, this post is part of series about refactoring Silverlight applications. So if you’re thinking why is the calculator class tightly coupled to the ViewModel? Find out how this can be resolved by applying SOLID design principles using MEF in Silverlight and WPF.

How NBuilder Could Help You Write Better .Net Unit Tests

One of the biggest challenges when creating unit tests is to come up test data. It makes sense having someone other than you test your code, so how about having someone other than you generate the test input for your .Net unit tests.

Data generation tools aren’t new concept and they come in many different forms. When I first saw Red Gate Sql Data Generator a couple of years ago, I thought to myself it’s a shame you need a database because this would have been great for unit and integration tests.

In this blog post I want to show you how NBuilder can be used when unit testing with .Net objects. The NBuilder assembly can be downloaded here http://code.google.com/p/nbuilder/.

In this blog post we will be using the product and category classes below

public class Product
{
    public Product()
    {
        Categories = new List<Category>();
    }

    public Guid Id { get; set; }
    public string Name { get; set; }
    public int Rating { get; set; }
    public decimal Price { get; set; }
    public bool InStock { get; set; }
    public List<Category> Categories { get; set; }

    public override string ToString()
    {
        return String.Format("Id:{0}, Name:{1}, Rating:{2}, Price:{3}, InStock:{4}, Categories:{5}", Id, Name, Rating, Price, InStock, Categories.Count);
    }
}

public class Category
{
    public string Name { get; set; }
}

NBuilder default values

The product class contains a variety of types. When you run the following code to create 10 products

[Test]
public void Should_Create_Ten_Products()
{
    var products = Builder<Product>.CreateListOfSize(10).Build();
    products.Count().ShouldEqual(10);
}

this is the output

IdNameRatingPriceInStockCategories Count
00000000-0000-0000-0000-000000000001Name111False0
00000000-0000-0000-0000-000000000002Name222True0
00000000-0000-0000-0000-000000000003Name333False0
00000000-0000-0000-0000-000000000004Name444True0
00000000-0000-0000-0000-000000000005Name555False0
00000000-0000-0000-0000-000000000006Name666True0
00000000-0000-0000-0000-000000000007Name777False0
00000000-0000-0000-0000-000000000008Name888True0
00000000-0000-0000-0000-000000000009Name999False0
00000000-0000-0000-0000-00000000000aName101010True0


  • For strings NBuilder suffixes the index number to the name of the property e.g. Name1
  • For numeric values such as int and decimal the default value is the index number
  • For guids a hexadecimal range is used
  • Boolean values alternate between true and false for each product
  • The categories collection is left empty. This would have been null if we didn’t create a new collection in the constructor of the product class

Changing how NBuilder default values are created

I really like how you can customize NBuilder and use your own convention for creating default values.

For example what if we wanted to change how guids are created.

One way to do this is to inherit from the RandomValuePropertyNamer class and override the GetGuid method as shown below.

public class JagsRandomValuePropertyNamer : RandomValuePropertyNamer
{
    protected override Guid GetGuid(System.Reflection.MemberInfo memberInfo)
    {
        return Guid.NewGuid();
    }
}

After setting the default property namer, all guids are created by calling Guid.NewGuid()

[Test]
public void Product_Should_Have_Guid_Assigned()
{
    BuilderSetup.SetDefaultPropertyNamer(new JagsRandomValuePropertyNamer());

    var product = Builder<Product>
        .CreateListOfSize(10)
        .WhereAll()
            .Have(p => p.Id = Guid.NewGuid())
        .Build();

    product[0].Id.ToString().ShouldNotEqual("00000000-0000-0000-0000-000000000001");
}

Using the WhereAll method to set the InStock to always be true

What if we wanted to change the InStock value to true for all the products in the collection. This can be done using the WhereAll method as shown in the code below

[Test]
public void All_Products_Should_Be_In_Stock()
{
    var products = Builder<Product>
        .CreateListOfSize(10)
        .WhereAll()
            .Have(p => p.InStock = true)
        .Build();

    products.All(p => p.InStock).ShouldBeTrue();
}

Using NBuilder to set parts of a collection

There are two ways you can use Nbuilder to set values in parts of a collection. The first is by using the first or last methods like so

[Test]
public void First_Two_Products_Should_Be_In_Stock()
{
    var products = Builder<Product>
        .CreateListOfSize(10)
        .WhereTheFirst(2)
            .Have(p => p.InStock = true)
        .Build();

    products[0].InStock.ShouldBeTrue();
    products[1].InStock.ShouldBeTrue();
}

the other is to use sections

[Test]
public void Mixture_Of_Products_In_Stock_Using_Sections()
{
    var products = Builder<Product>
        .CreateListOfSize(10)
        .WhereSection(0, 1)
            .Have(p => p.InStock = true)
        .WhereSection(2, 9)
            .Have(p => p.InStock = false)
        .Build();

    products[0].InStock.ShouldBeTrue();
    products[2].InStock.ShouldBeFalse();
}

Using the UniqueRandomList to create unique random lists…

So far we haven’t done anything with the category property.

What if you wanted to build a product collection with each product having a random number of categories?

By calling the HaveDoneToThem and the UniqueRandomList methods we can create a set of products with having different categories to one another

[Test]
public void Products_With_Random_Categories()
{
    var categories = Builder<Category>
        .CreateListOfSize(100)
        .Build();

    var products = Builder<Product>
        .CreateListOfSize(10)
        .WhereAll()
        .HaveDoneToThem(p => p.Categories.AddRange(Pick<Category>.UniqueRandomList(2).From(categories)))
        .Build();

    var productCategoryOne = products[0].Categories[0].Name;
    var productCategoryTwo = products[1].Categories[0].Name;

    productCategoryOne.ShouldNotBeTheSameAs(productCategoryTwo);
}

Extending NBuilder with a Lorem Ipsum string generator

One thing I really like about NBuilder is the ability to extend it.

The code below shows how easy it is to have product names randomly using Lorem Ipsum just by creating a extension method like this

public static class StringExtensions
{
    public const string LoremIpsum = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";

    public static IOperable<Product> HavingRandomLoremIpsumProductName(this IOperable<Product> operable)
    {
        ((IDeclaration<Product>)operable).ObjectBuilder.With(x => x.Name = LoremIpsum.Substring(0, new Random().Next(446)));
        return operable;
    }
}

this can be used to generate products with random names like this

[Test]
public void Products_With_Random_LoremIpsum_Names()
{
    var products = Builder<Product>
        .CreateListOfSize(10)
        .WhereAll()
            .HavingRandomLoremIpsumProductName()
        .Build();

    var nameOfProductOne = products[0].Name;
    var nameOfProductTwo = products[1].Name;

    nameOfProductOne.ShouldNotBeTheSameAs(nameOfProductTwo);
}

Jag Reehal’s Final Thought on ‘How NBuilder Could Help You Write Better .Net Unit Tests’

I think frameworks like NBehave could really have a big impact on how you go about having to create test data. The fluent interface is fantastic and it’s so easy to customize.

NBuilder contains a lot more features than I have covered in this post so if you like what you’ve seen make sure you check out the NBuilder documentation.

For the future I’m hoping Fluent NHibernate and NBuilder could work together. For example when you define class maps in Fluent NHibernate you can specify the length of string column. If NBuilder could use information like this when generating data that would really be something special.

Page 2 of 612345...Last »