BDD

.NET Musings

Wandering thoughts of a developer, architect, speaker, and trainer

NAVIGATION - SEARCH

Mocking Properties With JustMock Free Edition

In typical unit testing scenarios, mocking property getters and setters isn’t high on the list of areas of concern. Where it usually comes into play is when an entity’s properties’ values (or the act of setting them) are part of the scaffolding for the system under test.

An example is a scenario where entities are publishers of events and the system under test is the subscriber (as with INotifyPropertyChanged).  As an example, create a subscriber class that is listening for the PropertyChanged event on an entity.  When the event fires, a property on the subscriber is updated to the value a property on the entity.

public class Subscriber
{
    IEntity _entity;
    public string BoundDescription { get; internal set; }
    public Subscriber(IEntity entity)
    {
        _entity = entity;
        _entity.PropertyChanged += EntityPropertyChanged;
    }
    void EntityPropertyChanged(
        object sender, PropertyChangedEventArgs e)
    {
        switch (e.PropertyName)
        {
            case "":
            case "Description":
                BoundDescription = ((IEntity)sender).Description;
                break;
        }
    }
}

We want to test this code, but don’t want to add noise to the tests or hide implementation from the test by using a concrete class.  Before we show how to test this, lets show how to handle properties with JustMock Free Edition.

Mocking property getters works the same as any other mock arrangement (as shown in the following test).

[Test]
public void Should_Mock_Property_Getters()
{
    string val = "Foo";
    IEntity entity = Mock.Create<IEntity>();
    Mock.Arrange(() => entity.Description).Returns(val);
    Assert.AreEqual(val, entity.Description);
}

Mocking property setters is a little bit different.  Instead of Mock.Arrange, we use Mock.ArrangeSet.  In the first test, we verify that the framework behaves as we expect. (Note: I often will write unit tests like this to validate my understanding of how something behaves.  It’s not that I am testing JustMock, I’m testing my understanding of JustMock.)  In the second test, we show that when we use a Strict Mock, any value assignment for the setter that we don’t explicitly arrange will cause a MockException to be thrown.

[Test]
public void Should_Mock_Property_Setters()
{
    string val = "Foo";
    IEntity entity = Mock.Create<IEntity>();
    Mock.ArrangeSet(() => entity.Description = val);
    entity.Description = val;
}
[Test,ExpectedException(typeof(MockException))]
public void Should_Throw_Exception_When_Set_Isnt_Arranged()
{
    string val = "Foo";
    IEntity entity = Mock.Create<IEntity>(Behavior.Strict);
    Mock.ArrangeSet(() => entity.Description = "Bar");
    entity.Description = val;
}

Now, the meat of the post.  When a value is set on a property, the entity will raise the PropertyChanged event.  The subscriber listens for this event, and sets a property to the value of the property that changed on the entity.

We create a mock of the IEntity, and arrange both a getter and a setter.  The setter raises the appropriate event when executed (for more information on mocking events refer to this post).  The getter is called in the event handler of the subscriber.  Finally, we assert that the BoundDescription property is correct set on the subscriber.

[Test]
public void Should_Raise_Event_When_Setting_Value()
{
    string val = "Foo";
    IEntity entity = Mock.Create<IEntity>();
    Mock.ArrangeSet(() => entity.Description = val)
    .Raises(() => entity.PropertyChanged += null,
            new object[] {entity,new PropertyChangedEventArgs("Description")});
    Mock.Arrange(() => entity.Description).Returns(val);
    Subscriber sub = new Subscriber(entity);
    entity.Description = val;
    Assert.AreEqual(val, sub.BoundDescription);
}

Summary

When your code requires mocking properties, JustMock provides a very clean mechanism for mocking both setters and getters, and allows you to cover even more of your code simply and cleanly. Instead of hiding the behavior of the scaffolding (in this case the entity), it is very apparent to the reader of the test what is going on.

Happy Coding!

Managed Windows Shared Hosting by OrcsWeb