Welcome to Habanero Land!   Register  |  Login
You are here:   Blogs
  So, why do you need to register to download Habanero and access the additional materials? 
The success of any open source project is based on the community built around it. So go ahead, register / login and get involved!
Dec
20
Mon
Posted By Andrew on Monday, December 20, 2010
2926 Views


This is the sixth blog in a series of blogs I have put together whilst trying to find a solution for unit testing WPF Bindings.

The BindingTest class does what I had started out to achieve. That is, it can be used to test bindings on a WPF window or UserControl. The syntax however, can still be improved. I am hoping to end up with something that is easy to use and easy to understand. To achieve this I have wrapped the BindingTest class with a fluent interface. My new testing class is FluentBindingTest. Here is the code:

    public class FluentBindingTest
    {
        protected readonly List ShouldBeBoundProperties = new List();
        protected Window WpfWindow;
        protected UserControl WpfUserControl;
 
        public BindingTest BindingTest { get; private set; }
 
        public FluentBindingTest()
        {
            BindingTest = new BindingTest();
        }
 
        public FluentBindingTest OnWindow(Window window)
        {
            if (WpfWindow != null) throw new InvalidOperationException("Window has already been set.  
A FluentBindingTest works on a single Window. A call to OnUserControl will set the Window as well.");
            WpfWindow = window;
            return this;
        }
 
        public FluentBindingTest OnUserControl(UserControl userControl)
        {
 
            if (!(WpfWindow == null && WpfUserControl==null)) 
throw new InvalidOperationException("Window has already been set.  
A FluentBindingTest works on a single Window. A call to OnUserControl will set the Window as well.");
            WpfWindow = new Window {Content = userControl};
            WpfUserControl = userControl;
            return this;
        }
 
        public FluentBindingTest ShouldContainBindingForProperty(string boundPropertyName)
        {
            ShouldBeBoundProperties.Add(boundPropertyName);
            return this;
        }

            Assert.Fail(bindingFailureMessage.ToString());
        }
 
         public void Validate()
        {
            const string crlf = "\r\n";
 
            var bindingFailureMessage = new StringBuilder();
 
            WpfWindow.Show();
            try
            {
                BindingTest.OnFrameWorkElement(WpfWindow);
                foreach (var shouldBeBoundProperty in ShouldBeBoundProperties)
                {
                    var result = BindingTest.ForProperty(shouldBeBoundProperty);
                    if (result.BindingMatchType!=BindingMatchTypes.ExactMatch) 
				bindingFailureMessage.Append(result.Message + crlf);
                }
 
            }
            finally
            {
                WpfWindow.Close();                
            }
 
            if (bindingFailureMessage.Length <= 0) return;
            bindingFailureMessage.Append("Have you checked that you are using the correct TBoundObjectType for this Window or UserControl");

 
    }
}

And a test now looks like:

        [RequiresSTA]
        [Test]
        public void Test_Validate_WhenCalledOnUserControlWithCorrectSimpleBindings_ShouldValidate()
        {
            //---------------Set up test pack-------------------
            var fluentBindingTest = new FluentBindingTest();
            var part = new ComputerPart
                       {
                           Description = "Seagate 500Gb HDD",
                           PartCode = "HDD001",
                           Price = 1250,
                           Stock = 10,
                           Cost = 950
                       };
            part.Save();
             var partWindow = new WindowWithCorrectBindings {DataContext = part};
            //---------------Execute Test ----------------------
            fluentBindingTest.OnWindow(partWindow)
                                .ShouldContainBindingForProperty("Description")
                                .ShouldContainBindingForProperty("Price")
                                .ShouldContainBindingForProperty("Stock")
                                .ShouldContainBindingForProperty("Cost")
                //---------------Test Result -----------------------
                                .Validate();
        }

Now that’s more like it. As with BindingTest there are two important steps to remember:

  • Test methods need to be decorated with the [RequiresSTA] attribute
  • A TearDown method needs to be added to the test fixture with the following line of code

System.Windows.Threading.Dispatcher.CurrentDispatcher.InvokeShutdown();
Categories

 Top Viewed
 Habanero Cloud
 Archive
 
Monthly

    This website is best viewed in Internet Explorer 7 & 8; Firefox 3.6.11; Opera 10.63; & Safari 4.