Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing the Viewmodel

I am sort of new to TDD. I have started creating the properties I need on the view model as plain auto property.

public string Firstname { get; set; }

Then I create a test

[TestMethod]
[Tag("Property")]
public void FirstNameTest()
{
    ViewModel = new CustomerViewModel();
    ViewModel.PropertyChanged += (s, e) =>
                                     {
                                         Assert.AreEqual("Firstname", e.PropertyName);
                                         Assert.AreEqual("Test", ViewModel.Firstname);
                                     };
    ViewModel.Firstname = "Test";
}

Then I would extend the actual implementation to make the test pass like this:

public string Firstname
{
    get { return _contact.FirstName; }
    set
    {
        if (_contact.FirstName == value)
            return;

        _contact.FirstName = value;

        RaisePropertyChanged(() => Firstname);
    }
}

The problem I have is that test still passes for the Aut property. Any tip for me how i could improve my process?

like image 734
Houman Avatar asked Jan 30 '11 20:01

Houman


2 Answers

You can do something like this:

    [TestMethod]
    [Tag("Property")]
    public void FirstNameTest()
    {
        bool didFire = false;
        ViewModel = new CustomerViewModel();
        ViewModel.PropertyChanged += (s, e) =>
                                         {
                                             didFire = true;
                                             Assert.AreEqual("Firstname", e.PropertyName);
                                             Assert.AreEqual("Test", ViewModel.Firstname);
                                         };
        ViewModel.Firstname = "Test";
        Assert.IsTrue(didFire);
    }
like image 161
BFree Avatar answered Oct 29 '22 22:10

BFree


You could try writing the test to be asynchronous. Consider this test method:

[TestMethod]
[Asynchronous]
public void TestMethod1()
{
    TestViewModel testViewModel = new TestViewModel();

    bool firstNameChanged = false;

    testViewModel.PropertyChanged +=
        (s, e) =>
            {
                if (e.PropertyName == "FirstName")
                {
                    firstNameChanged = true;
                }
            };

    EnqueueCallback(() => testViewModel.FirstName = "first name");
    EnqueueConditional(() => firstNameChanged == true);
    EnqueueTestComplete();
}

Notice the Asynchronous attribute at the top of the method. There are two important methods here: EnqueueCallback and EnqueueTestComplete. EnqueueCallback will add lambda expressions to a queue and the test method will wait until the current callback is executed. In the case here, we subscribe to the PropertyChanged event on the ViewModel and we set a local boolean variable to true when the FirstName property notifies a change. We then Enqueue two callbacks: one to set the FirstName property and one to assert that the local boolean variable has changed value. Finally, we need to add a call to EnqueueTestComplete() so that the framework knows the test is over.

NOTE: In order to get EnqueueCallback and EnqueueTestComplete, you need to inherit from SilverlightTest on your test class. You also need to import Microsoft.Silverlight.Testing to get the Asynchronous attribute. It should look something like this:

using Microsoft.Silverlight.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Foo.Example.Test
{
    [TestClass]
    public class Tests : SilverlightTest
    {

        // ... tests go here
    }
}
like image 29
avanek Avatar answered Oct 29 '22 21:10

avanek