Mark Pearl
Mark Pearl

Reputation: 7673

Testing ViewModel PropertyChanged Events

I am a "beginner" at TDD, and something I am trying to figure is how to unit test viewmodels...

I am wanting to make sure that a property ProeprtyChanged event is fired... I have the following test using nunit.

[Test]        
public void Radius_Property_Changed()
{
    var result = false;
    var sut = new MainViewModel();
    sut.PropertyChanged += (s, e) =>
    {
        if (e.PropertyName == "Radius")
        {
            result = true;
        }
    };

    sut.Radius = decimal.MaxValue;
    Assert.That(result, Is.EqualTo(true));
}

Is this the cleanest way to do this, or is there a better way to test this property

... snippet of code in the viewmodel of the propety I am testing looks like this...

public decimal Radius
{
    get { return _radius; }
    set
    {
        _radius = value;
        OnPropertyChanged("Radius");
    }
}

Upvotes: 6

Views: 2968

Answers (4)

Preben Huybrechts
Preben Huybrechts

Reputation: 6111

I've made a simple class that you can use for this: github

It uses reflection to determin if a property changed event was raised when the value is set of a public property.

Example:


[TestMethod]
public void Properties_WhenSet_TriggerNotifyPropertyChanged()
{
    new NotifyPropertyChangedTester(new FooViewModel()).Test();
}

Upvotes: 0

Jonathan Allen
Jonathan Allen

Reputation: 70317

Granite's testing framework lets you write tests like this:

    [TestMethod]
    public void ChangeTrackingModelBase_BasicFunctionalityTest()
    {
        var person = new ChangeTrackingPerson();
        var eventAssert = new PropertyChangedEventAssert(person);

        Assert.IsNull(person.FirstName);
        Assert.AreEqual("", person.LastName);

        eventAssert.ExpectNothing();

        person.FirstName = "John";

        eventAssert.Expect("FirstName");
        eventAssert.Expect("IsChanged");
        eventAssert.Expect("FullName");

        person.LastName = "Doe";

        eventAssert.Expect("LastName");
        eventAssert.Expect("FullName");

        person.InvokeGoodPropertyMessage();
        eventAssert.Expect("FullName");

        person.InvokeAllPropertyMessage();
        eventAssert.Expect("");

    }

http://granite.codeplex.com/SourceControl/list/changesets

It is based on MSTest, but you could easily rewrite it to work with NUnit.

Upvotes: 1

Nicole Calinoiu
Nicole Calinoiu

Reputation: 20992

My own "minimal" test for this sort of thing is slightly different. Instead of checking that the event is raised, I would usually verify that is is raised exactly once.

Upvotes: 1

k.m
k.m

Reputation: 31454

This is pretty much how you do that. There's not much else to do here given it's pretty simple (and boring) code. It might be worth to wrap that in your own reusable library/tool. Or even better, use existing code.

Upvotes: 4

Related Questions