<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>My Public Interface &#187; TDD</title>
	<atom:link href="http://blog.roboblob.com/tag/tdd/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.roboblob.com</link>
	<description>and ideas for its refactoring...</description>
	<lastBuildDate>Fri, 16 Jul 2010 14:55:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Unit Testing Modal Dialogs in MVVM and Silverlight 4</title>
		<link>http://blog.roboblob.com/2010/04/21/unit-testing-modal-dialogs-in-mvvm-and-silverlight-4/</link>
		<comments>http://blog.roboblob.com/2010/04/21/unit-testing-modal-dialogs-in-mvvm-and-silverlight-4/#comments</comments>
		<pubDate>Wed, 21 Apr 2010 07:58:53 +0000</pubDate>
		<dc:creator>roboblob</dc:creator>
				<category><![CDATA[MVVM]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[ChildWindow]]></category>
		<category><![CDATA[Dialog]]></category>
		<category><![CDATA[ModalDialog]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[UnitTest]]></category>
		<category><![CDATA[UnitTesting]]></category>
		<category><![CDATA[ViewModel]]></category>

		<guid isPermaLink="false">http://blog.roboblob.com/?p=319</guid>
		<description><![CDATA[As feedback to my recent post on Modal Dialogs in MVVM and Silverlight 4 I have received comments that the solution is not easy to Unit Test so i decided to create small blog posts on this subject just to show how simple and clean it is to do this...]]></description>
			<content:encoded><![CDATA[Number of View: 3999<br/><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>As feedback to <a href="http://blog.roboblob.com/2010/01/19/modal-dialogs-with-mvvm-and-silverlight-4/" target="_blank">my recent post on Modal Dialogs in MVVM and Silverlight 4</a> I have received comments that the solution is not easy to Unit Test so i decided to create small blog posts on this subject just to show how simple and clean it is to do this.</p>
<p>So for those who are too lazy to read <a href="http://blog.roboblob.com/2010/01/19/modal-dialogs-with-mvvm-and-silverlight-4/" target="_blank">my original modal dialog post</a> here is a quick reminder:</p>
<ul>
<li>I presented a simple solution how to abstract modal dialogs and  message boxes in Silverlight 4 and call them from your ViewModel and act  according to the results returned from those modal dialogs.</li>
<li>I used Silverlight&#8217;s ChildWindow control because it was perfect fit for  that job.</li>
<li>Important thing is to say that ChildWindow control was used as  implementation (with its ViewModel off course) but was hidden by  abstractions (like IModalWindow and IModalWindowService) so it can  easily be changed by some other implementation and unit tested, mocked  out etc.</li>
</ul>
<p>So in this post i will use the same simple <a href="http://demos.roboblob.com/demos/Silverlight4/MVVM/MvvmModalDialogsUnitTesting/" target="_blank">Demo Application</a> for the previous modal dialogs post but I will add few Unit Tests using <a href="http://code.msdn.microsoft.com/silverlightut" target="_blank">Silverlight Unit Testing Framework</a> and <a href="http://www.ayende.com/projects/rhino-mocks/downloads.aspx" target="_blank">Silverlight verstion of RhinoMocks</a>.</p>
<p>Our <a href="http://demos.roboblob.com/demos/Silverlight4/MVVM/MvvmModalDialogsUnitTesting/" target="_blank">Sample app</a> is very simple and just shows a view with list of some User entities.</p>
<p>Each of users can be edited by clicking on EDIT button next to them &#8211; this shows a modal dialog with User editor, we can change details and save them by clicking on OK or CANCEL.</p>
<p>Also there is option to delete each User by clicking on the DEL button &#8211; Message Box is shown with OK/Cancel buttons &#8211; these are very common scenarios for every LOB application so that&#8217;s why i picked them.</p>
<p>I must admit that i improved my framework since the previous post &#8211; I changed the signature of the IModalDialogService a little because now in my framework i have a IViewInitializationService that wires up ViewModels with Views so all this is used in this posts just to show it off <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />   (more on the IViewInitializationService and the new way how i wire up ViewModels and View in one of the next posts).</p>
<p>So first let&#8217;s see the changes made to the IModalDialogView that is the abstraction of the actual modal dialog to be shown:</p>
<pre class="brush: csharp;">
  public interface IModalWindowView : IView
  {
    bool? DialogResult { get; set; }
    event EventHandler Closed;
    void Show();
    void Close();
  }
</pre>
<p>So the real ChildWindow that will be our dialog only needs to be marked as implementor of IModalWindowView interface with no additional code needed since this interface contains only methods and properties that ChildWindow already implements:</p>
<pre class="brush: csharp;">
    public partial class EditUserModalDialogView : IModalWindowView
    {
        public EditUserModalDialogView()
        {
            InitializeComponent();
        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }
    }
</pre>
<p>Also you could see that our IModalDialogView implements our old friend &#8211; IView:</p>
<pre class="brush: csharp;">
    public interface IView
    {
        object FindName(string name);
        object DataContext { get; set; }
        string Name { get; set; }
        event RoutedEventHandler Loaded;
    }
</pre>
<p>Again nothing to implement here &#8211; no code to add &#8211; because ChildWindow already implements all this since its inheriting the ContentContol that has all this.</p>
<p>So now lets see the MainPageViewModel for our MainPageView that will actually show the modal dialogs and message boxes:</p>
<pre class="brush: csharp;">
    public class MainPageViewModel : ViewModel
    {
        private readonly IModalDialogService modalDialogService;
        private readonly IMessageBoxService messageBoxService;
        private ObservableCollection&lt;User&gt; users = new ObservableCollection&lt;User&gt;();

        public MainPageViewModel(IModalDialogService modalDialogService, IMessageBoxService messageBoxService)
        {
          this.modalDialogService = modalDialogService;
          this.messageBoxService = messageBoxService;

          this.Users = new ObservableCollection&lt;User&gt;();

          for (int i = 1; i &lt; 6; i++ )
          {
            this.Users.Add(new User {Username = string.Format(&quot;Admin User {0}&quot;,
                new Random((int)DateTime.Now.Ticks).Next(10,100)), IsAdmin = true});
            Thread.Sleep(100);
          }

          this.ShowUserCommand =
              new DelegateCommand&lt;User&gt;(userInstanceToEdit =&gt;
                                      {
                                       this.modalDialogService.ShowDialog&lt;EditUserModalDialogViewModel&gt;
                                             (
                                             userInstanceToEdit,
                                             (dialog, returnedViewModelInstance) =&gt;
                                             {
                                                if (dialog.DialogResult.HasValue &amp;&amp; dialog.DialogResult.Value)
                                                {
                                                var oldItem = this.Users.FirstOrDefault( u =&gt; u.Id == userInstanceToEdit.Id);
                                                var oldPos = this.Users.IndexOf(oldItem);
                                                if (oldPos &gt; -1)
                                                {
                                                    this.Users.RemoveAt(oldPos);
                                                    this.Users.Insert(oldPos, returnedViewModelInstance.User);
                                                }
                                                }
                                            });
                                       });

          this.DeleteUserCommand = new DelegateCommand&lt;User&gt;
              (p =&gt;
                                    {
                                        var result = this.messageBoxService.Show(string.Format(
                                            &quot;Are you sure you want to delete user {0} ???&quot;, p.Username),
                                            &quot;Please Confirm&quot;, GenericMessageBoxButton.OkCancel);
                                        if (result == GenericMessageBoxResult.Ok)
                                        {
                                        this.Users.Remove(p);
                                        }});

        }

        public ObservableCollection&lt;User&gt; Users
        {
            get { return users; }
            set { users = value;
            this.OnPropertyChanged(&quot;Users&quot;);
            }
        }

        private ICommand showUserCommand;
        public ICommand ShowUserCommand
        {
            get { return showUserCommand; }
            set { showUserCommand = value;
                this.OnPropertyChanged(&quot;ShowUserCommand&quot;);
            }
        }

      private ICommand deleteUserCommand;
      public ICommand DeleteUserCommand
      {
        get { return deleteUserCommand; }
        set { deleteUserCommand = value;
        this.OnPropertyChanged(&quot;DeleteUserCommand&quot;);
        }
      }
    }
</pre>
<p>As you see ViewModel is simple class and it just has a list of Users to be shown by its View and important things to notice here are two commands for editing and deleting single user.</p>
<p><strong> ShowUserCommand </strong>shows modal dialog for editing single user, and <strong>DeleteUserCommand </strong>just shows MessageBox for confirmation of deletion with OK and Cancel buttons.</p>
<p>So now comes the fun part, lets write unit tests for those commands:</p>
<p>First UnitTest checks that our ShowUserCommand shows the modal dialog for editing the user (using the IModalDialogService). We put expectation on our IModalDialogService mock and invoke our command on ViewModel and verify all expectations afterwards.</p>
<p>Here is the code:</p>
<pre class="brush: csharp;">
        [TestMethod]
        public void ShowUserCommand_WhenCalledWithSpecificUser_ShowsModalDialogByPassingThatUserAsInitParam()
        {
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            modalDialogService.Expect(
                p =&gt; p.ShowDialog&lt;EditUserModalDialogViewModel&gt;(null, null))
                .Constraints(
                Is.Same(userToSend),
                Is.TypeOf(typeof(Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;)))
                .Repeat.Once();

            viewModel.ShowUserCommand.Execute(userToSend);

            modalDialogService.VerifyAllExpectations();
        }
</pre>
<p>We first get our ViewModel with Rhino-mocked instances of IModalDialogService and IMessageBoxService and some test Users by calling this methods:</p>
<pre class="brush: csharp;">
        private static ObservableCollection&lt;User&gt; GenerateSampleUsers()
        {
            return new ObservableCollection&lt;User&gt;()
                                  {
                                      new User() {Username = &quot;user 1&quot;},
                                      new User() {Username = &quot;user 2&quot;},
                                      new User() {Username = &quot;user 3&quot;}
                                  };
        }

        private MainPageViewModel GetInitializedAndMockedViewModel()
        {
            this.modalDialogService = MockRepository.GenerateMock&lt;IModalDialogService&gt;();
            this.messageBoxService = MockRepository.GenerateMock&lt;IMessageBoxService&gt;();
            return new MainPageViewModel(this.modalDialogService, this.messageBoxService);
        }
</pre>
<p>So that was easy or what?</p>
<p>Lets go to next Unit Test. Lets check that when we call ShowUserCommand with instance of User that when it shows dialog and dialog returns true as its DialogResult &#8211; that we replace the original User in ViewModel&#8217;s list of Users with the one we got from the modal dialog:</p>
<pre class="brush: csharp;">
        [TestMethod]
        public void ShowUserCommand_WhenCalledWithSpecificUserAndOnModalDialogResultIsTrue_ShouldReplaceTheOriginalUserInstanceWithOneReturnedFromModel()
        {
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            var dialog = MockRepository.GenerateMock&lt;IModalWindowView&gt;();
            dialog.Expect(p =&gt; p.DialogResult).Return(true);

            var mockViewModel = MockRepository.GenerateStub&lt;EditUserModalDialogViewModel&gt;();
            mockViewModel.User = new User() {Username = &quot;mocked&quot;};

            modalDialogService.Expect(
                p =&gt; p.ShowDialog&lt;EditUserModalDialogViewModel&gt;(null, null))
                .Constraints(
                    Is.Same(userToSend),
                    Is.TypeOf(typeof (Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;)))
                .Repeat.Once().WhenCalled(
                    m =&gt;
                        {
                            var action = (m.Arguments[1] as Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;);
                            if (action != null)
                            {
                                action.Invoke(dialog, mockViewModel);
                            }
                        });

            viewModel.ShowUserCommand.Execute(userToSend);

            Assert.AreEqual(&quot;mocked&quot;, viewModel.Users[1].Username);
        }
</pre>
<p>And here is the unit test that checks the DeleteUserCommand so that it actually deletes the user from the ViewModel&#8217;s list of users if OK button was clicked on the shown message box:</p>
<pre class="brush: csharp;">
        [TestMethod]
        public void DeleteUserCommand_WhenCalledWithSpecificUserAndCallToMessageBoxServiceReturnsOk_ShouldDeleteThatUser()
        {
            // arrange
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            this.messageBoxService.Expect(p =&gt; p.Show(null, null, GenericMessageBoxButton.OkCancel)).Constraints(
                Is.Anything(), Is.Anything(),
                Is.Anything()).Return(GenericMessageBoxResult.Ok);

            // act
            viewModel.DeleteUserCommand.Execute(userToSend);

            // assert user is not there anymore
            Assert.IsFalse(viewModel.Users.Any( u =&gt; u.Username == userToSend.Username));
        }
</pre>
<p>So it turned out that its quite simple to test Modal Dialogs as long as you have the proper abstractions in place <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
You can <a href="http://demos.roboblob.com/demos/Silverlight4/MVVM/MvvmModalDialogsUnitTesting/tests.aspx" target="_blank">open this page to see all the unit tests running in browser</a>.</p>
<p>Those tests are actually running on the code from the sample demo app!</p>
<p>And as you see all the Unit Tests are green, and the world is safe again <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Here is the code for all the tests, that is &#8211; all 9 of them:</p>
<pre class="brush: csharp;">
namespace UnitTestingModalDialogs.Tests
{
    [TestClass]
    public class MainPageViewModelTests
    {
        private IModalDialogService modalDialogService;
        private IMessageBoxService messageBoxService;

        private static ObservableCollection&lt;User&gt; GenerateSampleUsers()
        {
            return new ObservableCollection&lt;User&gt;()
                                  {
                                      new User() {Username = &quot;user 1&quot;},
                                      new User() {Username = &quot;user 2&quot;},
                                      new User() {Username = &quot;user 3&quot;}
                                  };
        }

        private MainPageViewModel GetInitializedAndMockedViewModel()
        {
            this.modalDialogService = MockRepository.GenerateMock&lt;IModalDialogService&gt;();
            this.messageBoxService = MockRepository.GenerateMock&lt;IMessageBoxService&gt;();
            return new MainPageViewModel(this.modalDialogService, this.messageBoxService);
        }

        [TestMethod]
        public void ShowUserCommand_WhenCalledWithSpecificUser_ShowsModalDialogByPassingThatUserAsInitParam()
        {
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            modalDialogService.Expect(
                p =&gt; p.ShowDialog&lt;EditUserModalDialogViewModel&gt;(null, null))
                .Constraints(
                Is.Same(userToSend),
                Is.TypeOf(typeof(Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;)))
                .Repeat.Once();

            viewModel.ShowUserCommand.Execute(userToSend);

            modalDialogService.VerifyAllExpectations();
        }

        [TestMethod]
        public void ShowUserCommand_WhenCalledWithSpecificUserAndOnModalDialogResultIsTrue_ShouldReplaceTheOriginalUserInstanceWithOneReturnedFromModel()
        {
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            var dialog = MockRepository.GenerateMock&lt;IModalWindowView&gt;();
            dialog.Expect(p =&gt; p.DialogResult).Return(true);

            var mockViewModel = MockRepository.GenerateStub&lt;EditUserModalDialogViewModel&gt;();
            mockViewModel.User = new User() {Username = &quot;mocked&quot;};

            modalDialogService.Expect(
                p =&gt; p.ShowDialog&lt;EditUserModalDialogViewModel&gt;(null, null))
                .Constraints(
                    Is.Same(userToSend),
                    Is.TypeOf(typeof (Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;)))
                .Repeat.Once().WhenCalled(
                    m =&gt;
                        {
                            var action = (m.Arguments[1] as Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;);
                            if (action != null)
                            {
                                action.Invoke(dialog, mockViewModel);
                            }
                        });

            viewModel.ShowUserCommand.Execute(userToSend);

            Assert.AreEqual(&quot;mocked&quot;, viewModel.Users[1].Username);
        }

        [TestMethod]
        public void ShowUserCommand_WhenCalledWithSpecificUserAndOnModalDialogResultIsFalse_ShouldNotReplaceTheItemInViewModelWithOneReceivedFromDialog()
        {
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            var dialog = MockRepository.GenerateMock&lt;IModalWindowView&gt;();
            dialog.Expect(p =&gt; p.DialogResult).Return(false);

            var mockViewModel = MockRepository.GenerateStub&lt;EditUserModalDialogViewModel&gt;();
            mockViewModel.User = new User() { Username = &quot;mocked&quot; };

            modalDialogService.Expect(
                p =&gt; p.ShowDialog&lt;EditUserModalDialogViewModel&gt;(null, null))
                .Constraints(
                    Is.Same(userToSend),
                    Is.TypeOf(typeof(Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;)))
                .Repeat.Once().WhenCalled(
                    m =&gt;
                    {
                        var action = (m.Arguments[1] as Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;);
                        if (action != null)
                        {
                            action.Invoke(dialog, mockViewModel);
                        }
                    });

            viewModel.ShowUserCommand.Execute(userToSend);

            Assert.AreNotEqual(&quot;mocked&quot;, viewModel.Users[1].Username);
        }

        [TestMethod]
        public void ShowUserCommand_WhenCalledWithSpecificUserAndOnModalDialogResultIsNull_ShouldNotReplaceTheItemInViewModelWithOneReceivedFromDialog()
        {
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            var dialog = MockRepository.GenerateMock&lt;IModalWindowView&gt;();
            dialog.Expect(p =&gt; p.DialogResult).Return(null);

            var mockViewModel = MockRepository.GenerateStub&lt;EditUserModalDialogViewModel&gt;();
            mockViewModel.User = new User() { Username = &quot;mocked&quot; };

            modalDialogService.Expect(
                p =&gt; p.ShowDialog&lt;EditUserModalDialogViewModel&gt;(null, null))
                .Constraints(
                    Is.Same(userToSend),
                    Is.TypeOf(typeof(Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;)))
                .Repeat.Once().WhenCalled(
                    m =&gt;
                    {
                        var action = (m.Arguments[1] as Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;);
                        if (action != null)
                        {
                            action.Invoke(dialog, mockViewModel);
                        }
                    });

            viewModel.ShowUserCommand.Execute(userToSend);

            Assert.AreNotEqual(&quot;mocked&quot;, viewModel.Users[1].Username);
        }

        [TestMethod]
        public void DeleteUserCommand_WhenCalledWithSpecificUser_ShouldCallMessageBoxServiceWithSomeTextThatContainsThatUsersUsername()
        {

            // arrange
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            this.messageBoxService.Expect(p =&gt; p.Show(null, null, GenericMessageBoxButton.OkCancel)).Constraints(
                Is.Matching&lt;string&gt;(txt =&gt; txt.Contains(userToSend.Username)), Is.Anything(),
                Is.Equal(GenericMessageBoxButton.OkCancel)).Return(GenericMessageBoxResult.Ok);

            // act
            viewModel.DeleteUserCommand.Execute(userToSend);

            // assert
            this.messageBoxService.VerifyAllExpectations();
        }

        [TestMethod]
        public void DeleteUserCommand_WhenCalledWithSpecificUser_ShouldCallMessageBoxServiceWithOkCancelParamForButtons()
        {

            // arrange
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            this.messageBoxService.Expect(p =&gt; p.Show(null, null, GenericMessageBoxButton.OkCancel)).Constraints(
                Is.Anything(), Is.Anything(),
                Is.Equal(GenericMessageBoxButton.OkCancel)).Return(GenericMessageBoxResult.Ok);

            // act
            viewModel.DeleteUserCommand.Execute(userToSend);

            // assert
            this.messageBoxService.VerifyAllExpectations();
        }

        [TestMethod]
        public void DeleteUserCommand_WhenCalledWithSpecificUserAndCallToMessageBoxServiceReturnsOk_ShouldDeleteThatUser()
        {
            // arrange
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            this.messageBoxService.Expect(p =&gt; p.Show(null, null, GenericMessageBoxButton.OkCancel)).Constraints(
                Is.Anything(), Is.Anything(),
                Is.Anything()).Return(GenericMessageBoxResult.Ok);

            // act
            viewModel.DeleteUserCommand.Execute(userToSend);

            // assert user is not there anymore
            Assert.IsFalse(viewModel.Users.Any( u =&gt; u.Username == userToSend.Username));
        }

        [TestMethod]
        public void DeleteUserCommand_WhenCalledWithSpecificUserAndCallToMessageBoxServiceReturnsCancel_ShouldNOTDeleteThatUser()
        {
            // arrange
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            this.messageBoxService.Expect(p =&gt; p.Show(null, null, GenericMessageBoxButton.OkCancel)).Constraints(
                Is.Anything(), Is.Anything(),
                Is.Anything()).Return(GenericMessageBoxResult.Cancel);

            // act
            viewModel.DeleteUserCommand.Execute(userToSend);

            // assert user is not there anymore
            Assert.IsTrue(viewModel.Users.Any(u =&gt; u.Username == userToSend.Username));
        }

        [TestMethod]
        public void DeleteUserCommand_WhenCalledWithSpecificUserAndCallToMessageBoxServiceReturnsCancel_ShouldNOTDeleteAnyUser()
        {
            // arrange
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            this.messageBoxService.Expect(p =&gt; p.Show(null, null, GenericMessageBoxButton.OkCancel)).Constraints(
                Is.Anything(), Is.Anything(),
                Is.Anything()).Return(GenericMessageBoxResult.Cancel);

            var usersCountBefore = viewModel.Users.Count;
            // act
            viewModel.DeleteUserCommand.Execute(userToSend);

            // assert user is not there anymore
            Assert.AreEqual(usersCountBefore, viewModel.Users.Count);
        }

    }
}
</pre>
<p>If you want to investigate further <a href="http://demos.roboblob.com/Silverlight4/MVVM//MvvmModalDialogsUnitTesting/UnitTestingModalDialogsSolution.zip" target="_self">download the Visual Studio 2010 solution </a>and play with it &#8211; feel free to use the code as you wish and remember to have fun!</p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F&amp;title=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F&amp;title=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F&amp;title=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F&amp;headline=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4&amp;u=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F&amp;title=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4&amp;summary=&amp;source=" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://blog.roboblob.com/2010/04/21/unit-testing-modal-dialogs-in-mvvm-and-silverlight-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unit Testable WCF Web Services in MVVM and Silverlight 4</title>
		<link>http://blog.roboblob.com/2010/04/11/unit-testable-wcf-web-services-in-mvvm-and-silverlight-4/</link>
		<comments>http://blog.roboblob.com/2010/04/11/unit-testable-wcf-web-services-in-mvvm-and-silverlight-4/#comments</comments>
		<pubDate>Sun, 11 Apr 2010 21:00:19 +0000</pubDate>
		<dc:creator>roboblob</dc:creator>
				<category><![CDATA[MVVM]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[DataBinding]]></category>
		<category><![CDATA[Mocking]]></category>
		<category><![CDATA[Mocks]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[ViewModel]]></category>
		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://blog.roboblob.com/?p=255</guid>
		<description><![CDATA[Number of View: 28755 In all my previous MVVM in Silverlight 4 posts i was avoiding to address one painful aspect of the Silverlight: calling WCF Web Services. And it was not without reason. Lets face it, consuming WCF Web Services from your Silverlight application can be pretty hard. I mean hard to do it]]></description>
			<content:encoded><![CDATA[Number of View: 28755<br/><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>In all my previous <a title="mvvm in silverlight 4 blog posts" href="http://blog.roboblob.com/tag/mvvm/" target="_blank">MVVM in Silverlight 4 posts</a> i was avoiding to address one painful aspect of the Silverlight: calling WCF Web Services.</p>
<p>And it was not without reason. Lets face it, consuming WCF Web Services from your Silverlight  application can be pretty hard.</p>
<p>I mean hard to do it in a clean way off course.</p>
<p>Yes we all know how to create a Silverlight enabled WCF Web Service from Visual Studio but things become messy from that point.</p>
<p>First question is how to invoke methods of the web service?</p>
<p>Should we use Add Web Service Reference from the Visual Studio and and get the service proxy generated for us by the IDE?</p>
<p>If you go down that route, its easy to start and you will be invoking web service methods asynchronously in no time, but you will pay the price for that simplicity later, that is for sure.</p>
<p>Next problem is how to Unit Test those web service calls &#8211; its impossible to abstract the generated proxy in a clean way.</p>
<p>Then if you change your Web Service signature, you have to rebuild your Proxy. This can be troublesome especially if more than one person is working on the same project (can be avoided using build scripts to rebuild proxy automatically during compilation but still i don&#8217;t like that).</p>
<p>Also invoking web service methods asynchronously is tedious work in terms of writing the same code over and over again.</p>
<p>You have to subscribe to the OnCompleted event, and then invoke the actual asynchronous method, and then when your OnComplete handler is invoked, you can process the results of the web service method.</p>
<p>Not to mention the lifetime of the generated proxy, and handling exceptions that could be thrown in the service etc.</p>
<p>So as we see Visual Studio (or command line) proxy generating helps us in many ways but also brings new problems that are hard to solve.</p>
<p>I figured that there has to be a better way to solve this everyday problem so while working on my personal MVVM framework (yes, everyone is building one these days) i was setting these goals regarding the Web Service calls from my MVVM applications:</p>
<ol>
<li>simplify as much as possible asynchronous invocation of Web Service methods (avoid writing boring boilerplate code for each call)</li>
<li>get rid of the Add Service Reference approach completely if possible</li>
<li>make the Web Services unit testable (hide them behind some interface so we can mock them in our unit tests)</li>
<li>simplify exception handling</li>
<li>fault tolerance (if web service client is faulted by exception it should be automatically recreated)</li>
</ol>
<p>If this list of features looks interesting to you then you will soon see that all this is possible in a simple way by using ChannelFactory&lt;T&gt; and creating the Web Service client channel for the web service manually.</p>
<p>So lets start:  In our example we will be using a fake WeatherForecast web service that will have just one method GetForecast and it will accept DateTime as parameter and return a simple class DailyForecast as a result that will have some fake data just to have something to work with.</p>
<p>First of all we need to create a service contract interface for WeatherForecastWebService and since we must allow the Silverlight client to call this web service asynchronously we will add conditional compilation code regions in the interface with additional asynchronous signatures for the GetForecast method (BeginGetForecast and EndGetForecast) like this:</p>
<pre class="brush: csharp;">
namespace Abstractions
{
    [ServiceContract]
    public interface IWeatherForecastService
    {

#if SILVERLIGHT
        [OperationContract(AsyncPattern=true)]
        IAsyncResult BeginGetForecast(DateTime day, AsyncCallback callback, object state);
        DailyForecast EndGetForecast(IAsyncResult result);
#else

        [OperationContract]
        DailyForecast GetForecast(DateTime day);
#endif
    }
}
</pre>
<p>and here is the DailyForecast Data Transfer Object (DTO) class that we will receive from the web service:</p>
<pre class="brush: csharp;">
namespace Abstractions
{
    [DataContract]
    public class DailyForecast
    {
        [DataMember]
        public DateTime Date { get; set; }

        [DataMember]
        public string Description { get; set; }
    }
}
</pre>
<p>Note the DataContract and DataMember attributes, they must be provided in order to receive the class on the client properly.</p>
<p>Since we are to consume the web service on the Silverlight client we must make available all the classes to the client side.</p>
<p>Here is how we are going to accomplish this: We must define service contract interface and all the classes that the service will return both on server and on the Silverlight client.  We will do that by creating a <strong>Abstractions.Web</strong> class library project that will hold the service contract interface IWeatherForecastService all the needed Data Transfer Object classes (in this example its just DailyForecast class), and then we will also create <strong>Abstractions.Silverlight </strong>- Silverlight class library project where we will add the same classes (DTO&#8217;s and service contract interface) as links &#8211; by going to to right click menu on the project and choose Add -&gt; Existing Item and add all needed files and click on Add As Link button instead of Add button.</p>
<p>here is how this setup looks in my Visual Studio instance:  <a href="http://blog.roboblob.com/wp-content/uploads/2010/04/AbstractionsProjectsVisualStudio.jpg"><img class="aligncenter size-medium wp-image-260" title="AbstractionsProjectsVisualStudio" src="http://blog.roboblob.com/wp-content/uploads/2010/04/AbstractionsProjectsVisualStudio-300x272.jpg" alt="" width="300" height="272" /></a> So now that we have same set of shared classes on client and on the server we can proceed with creating a web service helper class that will allow us to invoke asynchronous methods in a simple way without having to do lot of boilerplate code.  As we said we want to be able to mock that helper in our Unit Tests we need to have an interface for it so lets define that first:</p>
<pre class="brush: csharp;">
namespace Framework.Abstractions.Silverlight.WebServices
{
    public interface IWebServiceClientFactory&lt;TWebService&gt; :  IDisposable
    {
        TWebService WebServiceInstance
        {
            get;
        }

        void Invoke&lt;TParam, TResult&gt;(TParam param, object state,
                                     Func&lt;TParam, AsyncCallback, object, IAsyncResult&gt; beginOp,
                                     Func&lt;IAsyncResult, TResult&gt; endOp,
                                     Action&lt;AsyncWebServiceCallResult&lt;TResult&gt;&gt; onComplete);

    }
}
</pre>
<p>As you can see we are defining the WebServiceClientFactory of TWebService that will expose a web service client instance WebServiceInstance if we want to call it directly but more important will be the generic <strong>Invoke </strong>method for generic asynchronous calls that will allow to call any method on any web service in a simple way just by specifying the parameter, then the begin and end method we want to calla and a method that should be called with the received results when web service call is finished.</p>
<p>Our helper class will also implement IDisposable so we can cleanup properly.</p>
<p>Let us investigate the Invoke method. From its signature we see that it is a generic function and that it has two type parameters, <strong>TParam </strong>that is the type of the parameter sent to our web service when we invoke the web method, and <strong>TResult </strong>that is the type of the result we expect from the method.</p>
<p>Then there is a object state that we want to send to the web service method (we can pass NULL there if we don&#8217;t need it).</p>
<p>And then comes the fun part: Parameter <strong>beginOp </strong>is a BEGIN* method that will be invoked, and parameter <strong>endOp </strong>is the END* method that will be invoked for the web service call. In our case we will supply here BeginGetForecast and EndGetForecast methods using the WebServiceInstance property of the same factory class. But its important to note here that if our web service would have other methods that support asynchronous invoking with these BEGIN* and END* signatures, we could call them in same way, just passing another pair of Begin* and End* methods.</p>
<p>Last parameters is an Action&gt; that will be called when the web method call is finished. This action will receive the instance of custom generic class AsyncWebServiceCallResult whose type parameter is the DailyForecast &#8211; result we would normally expect from the web method.  So here is the definition of generic AsyncWebServiceCallResult class:</p>
<pre class="brush: csharp;">
namespace Framework.Abstractions.Silverlight.WebServices
{
    public class AsyncWebServiceCallResult&lt;TResult&gt;
    {
        public TResult Result { get; set; }
        public bool WasSuccessfull { get; set;}
        public Exception Exception { get; set; }
    }
}
</pre>
<p>So this class is just a wrapper around the TResult we would usually receive from the web service method call and it adds just two more properties: boolean <strong>WasSuccessfull </strong>and <strong>Exception</strong>.  If web method call is executed without problems WasSuccessfull is set to true and Exception is null, and on the other hand if there is some exception thrown during the invocation of the web service method call Exception will hold the Exception thrown and WasSuccessfull will be set to false.</p>
<p>So lets see how we would use this Web Service factory to call our WeatherForecastService:</p>
<pre class="brush: csharp;">
var weatherServiceFactory = SimpleServiceLocator.Instance.Retrieve&lt;IWebServiceClientFactory&lt;IWeatherForecastService&gt;&gt;();
weatherServiceFactory.Invoke(date, null,
                                          weatherServiceFactory.WebServiceInstance.BeginGetForecast,
                                          weatherServiceFactory.WebServiceInstance.EndGetForecast,
                                          this.OnResultReceived);
</pre>
<p>And the method that will be called when results is received would look like this:</p>
<pre class="brush: csharp;">
        private void OnResultReceived(AsyncWebServiceCallResult&lt;DailyForecast&gt; asyncResult)
        {
            if (asyncResult.WasSuccessfull)
            {
                this.StatusMessage = &quot;New forecast received ok.&quot;;
                this.ForecastThatWasReceived = asyncResult.Result;

            }
            else
            {
                this.ForecastThatWasReceived = null;
                this.StatusMessage = &quot;Error result received: Error description: &quot; + asyncResult.Exception.Message;
            }
        }
</pre>
<p>And you can use this generic helper class to create wrapper around ANY web service exposed to your Silverlight application.</p>
<p>You just instantiate this class giving it the contract interface of the desired web service and URL of the web service.</p>
<p>WebServiceClientFactory will do all the plumbing for you and create ChannelFactory and web service client and expose it in WebServiceInstance property.</p>
<p>Then you can use Invoke method of the class to call ANY web service method with single line of code (you need on complete action to receive the result but you cannot avoid that &#8211; its asynchronous call after all).</p>
<p>Usable?  <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>So now that you have seen how we would use the interface of our web service factory, lets see how its really implemented:</p>
<pre class="brush: csharp;">
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Windows;
using Framework.Abstractions.Silverlight.WebServices;
using System.Linq.Expressions;

namespace Framework.Implementors.Silverlight.WebServices
{
    public class WebServiceClientFactory&lt;TWebService&gt; : IWebServiceClientFactory&lt;TWebService&gt; where  TWebService : class
    {
        private CustomBinding binding;
        private readonly string endpointAddress;
        private ChannelFactory&lt;TWebService&gt; channelFactory;

        public WebServiceClientFactory(CustomBinding binding, string endpointAddress)
        {
            this.binding = binding;
            this.endpointAddress = endpointAddress;
        }

        public WebServiceClientFactory(string endpointAddress)
        {
            this.endpointAddress = endpointAddress;
        }

        public TWebService WebServiceInstance
        {
            get
            {
                if (this.channelFactory == null || this.channel == null)
                {
                    this.InitializeWeatherServiceClient();
                }

                return this.channel;
            }

            private set
            {
                this.channel = value;
            }
        }
        private TWebService channel;

        private void InitializeWeatherServiceClient()
        {
            Debug.WriteLine(&quot;Initializing factory and channel in &quot; + this.GetType().Name);
            if (this.binding == null)
            {
                var elements = new List&lt;BindingElement&gt;();
                elements.Add(new BinaryMessageEncodingBindingElement());
                elements.Add(new HttpTransportBindingElement());
                this.binding = new CustomBinding(elements);
            }

            channelFactory = new ChannelFactory&lt;TWebService&gt;(this.binding, new EndpointAddress(endpointAddress));
            channel = this.GetNewChannelFromCurrentFactory();
        }

        public void Invoke&lt;TParam, TResult&gt;(TParam param, object state, Func&lt;TParam, AsyncCallback, object, IAsyncResult&gt; beginOp, Func&lt;IAsyncResult, TResult&gt; endOp, Action&lt;AsyncWebServiceCallResult&lt;TResult&gt;&gt; onComplete)
        {
            beginOp(param, (ar) =&gt;
                {
                    var asyncResult = new AsyncWebServiceCallResult&lt;TResult&gt;();
                    try
                    {
                        asyncResult.Result = endOp(ar);
                        asyncResult.WasSuccessfull = true;
                    }
                    catch (Exception e)
                    {
                        asyncResult.WasSuccessfull = false;
                        asyncResult.Exception = e;
                    }

                    if (Deployment.Current.Dispatcher.CheckAccess())
                    {
                        onComplete(asyncResult);
                    }
                    else
                    {
                        Deployment.Current.Dispatcher.BeginInvoke(() =&gt; onComplete(asyncResult));
                    }

                }, state );
        }

        private TWebService GetNewChannelFromCurrentFactory()
        {

            var newChannel = channelFactory.CreateChannel();

            var channelAsCommunicationObject = (newChannel as ICommunicationObject);
            if (channelAsCommunicationObject != null)
            {
                channelAsCommunicationObject.Faulted += ChannelFaulted;
            }

            return newChannel;
        }

        void ChannelFaulted(object sender, EventArgs e)
        {
            Debug.WriteLine(&quot;Service channel faulted in &quot; + this.GetType().Name);
            var communicationObject = (this.channel as ICommunicationObject);
            if (communicationObject != null)
            {
                communicationObject.Abort();

                this.channel = this.GetNewChannelFromCurrentFactory();
            }
        }

        ~WebServiceClientFactory()
        {
            Dispose(false);
        }

        public void Dispose()
        {
            Dispose(true);
        }

        protected void Dispose(bool disposing)
        {
            if (disposing)
            {
                // dispose managed stuff
                Debug.WriteLine(&quot;Disposing managed resources in &quot; + this.GetType().Name);
                var communicationObject = (this.channel as ICommunicationObject);
                if (communicationObject != null)
                {
                    communicationObject.Faulted -= this.ChannelFaulted;

                    try
                    {
                        communicationObject.Close();
                    }
                    catch (Exception)
                    {
                        try
                        {
                            communicationObject.Abort();
                        }
                        catch
                        {
                        }
                    }
                }
            }

            // here we would dispose unmanaged stuff
        }

    }
}
</pre>
<p>Class has multiple constructors so you can choose how to set it up. The simplest usage is just to specify the string URL of the web service. Here is how i setup my IOC in the bootstrapper of my Silverlight application:</p>
<pre class="brush: csharp;">
SimpleServiceLocator.Instance.RegisterAsSingleton&lt;IWebServiceClientFactory&lt;IWeatherForecastService&gt;&gt;
(new WebServiceClientFactory&lt;IWeatherForecastService&gt;(&quot;http://localhost:1000/WeatherForecastService.svc&quot;));
</pre>
<p>When constucted like this factory class uses standard Binding that would be created for you if you would add the Web Service Reference from visual studio and it will use that Binding and that given URL as endpoint to create a generic ChannelFactory of the web service type provided in  type param</p>
<p>&lt;TWebService&gt; and then it will create a communication channel to communicate with web service of given type on the given URL.</p>
<p>Here is the code that is doing this part:</p>
<pre class="brush: csharp;">
        private void InitializeWeatherServiceClient()
        {
            Debug.WriteLine(&quot;Initializing factory and channel in &quot; + this.GetType().Name);
            if (this.binding == null)
            {
                var elements = new List&lt;BindingElement&gt;();
                elements.Add(new BinaryMessageEncodingBindingElement());
                elements.Add(new HttpTransportBindingElement());
                this.binding = new CustomBinding(elements);
            }

            channelFactory = new ChannelFactory&lt;TWebService&gt;(this.binding, new EndpointAddress(endpointAddress));
            channel = this.GetNewChannelFromCurrentFactory();
        }
</pre>
<p>There is a another constructor that accepts Binding if you want to provide your own.<br />
Next interesting part of the class is the Invoke method:</p>
<pre class="brush: csharp;">
        public void Invoke&lt;TParam, TResult&gt;(TParam param, object state, Func&lt;TParam, AsyncCallback, object, IAsyncResult&gt; beginOp, Func&lt;IAsyncResult, TResult&gt; endOp, Action&lt;AsyncWebServiceCallResult&lt;TResult&gt;&gt; onComplete)
        {
            beginOp(param, (ar) =&gt;
                {
                    var asyncResult = new AsyncWebServiceCallResult&lt;TResult&gt;();
                    try
                    {
                        asyncResult.Result = endOp(ar);
                        asyncResult.WasSuccessfull = true;
                    }
                    catch (Exception e)
                    {
                        asyncResult.WasSuccessfull = false;
                        asyncResult.Exception = e;
                    }

                    if (Deployment.Current.Dispatcher.CheckAccess())
                    {
                        onComplete(asyncResult);
                    }
                    else
                    {
                        Deployment.Current.Dispatcher.BeginInvoke(() =&gt; onComplete(asyncResult));
                    }

                }, state );
        }
</pre>
<p>As you can see no big deal there, we just invoke the BEGIN* operation with lambda method as complete handler where we wrap the call to END* operation in Try..Catch so we can recover from any exception.<br />
If there was an exception we set WasSuccessfull to false and Exception property.<br />
If all went ok we populate the Result property with the result of the web method call and then we invoke the onComplete action that was supplied by the user of the class.<br />
But we make sure that we invoke it on the UI thread just as a convenience for the user so he does not need to do it by himself.</p>
<p>One more important thing is that if our web service channel gets faulted by some communication error we will catch that event and recreate the channel:</p>
<pre class="brush: csharp;">
        void ChannelFaulted(object sender, EventArgs e)
        {
            Debug.WriteLine(&quot;Service channel faulted in &quot; + this.GetType().Name);
            var communicationObject = (this.channel as ICommunicationObject);
            if (communicationObject != null)
            {
                communicationObject.Abort();

                this.channel = this.GetNewChannelFromCurrentFactory();
            }
        }
</pre>
<p>Previously, we subscribed that method to the OnFaulted event on the channel.</p>
<p>Other parts of the class are not too much interesting so you can dig yourself if you want.</p>
<p>So lets see how we would use the class in our view model.<br />
Here is the listing of the ForecastViewModel that will allow us to invoke the WeatherForecast web service:</p>
<pre class="brush: csharp;">
using System;
using Abstractions;
using Framework.Abstractions.Silverlight.Intefaces;
using Framework.Abstractions.Silverlight.WebServices;
using Framework.Implementors.Silverlight.Comanding;
using Framework.Implementors.Silverlight.MVVM;

namespace ViewModels
{
    public class ForecastViewModel : ViewModel
    {
        private readonly IWebServiceClientFactory&lt;IWeatherForecastService&gt; weatherServiceFactory;

        public ForecastViewModel(IWebServiceClientFactory&lt;IWeatherForecastService&gt; weatherServiceFactory)
        {
            this.weatherServiceFactory = weatherServiceFactory;

            this.GetForecastCommand =
                new DelegateCommand&lt;DateTime&gt;(
                    date =&gt;
                    {
                        this.StatusMessage = string.Format(&quot;Invoking web service with parameter {0}&quot;, date.ToString());
                        this.weatherServiceFactory.Invoke(
date,
null,
this.weatherServiceFactory.WebServiceInstance.BeginGetForecast,

this.weatherServiceFactory.WebServiceInstance.EndGetForecast,

this.OnResultReceived);

                    });

        }

        private void OnResultReceived(AsyncWebServiceCallResult&lt;DailyForecast&gt; asyncResult)
        {
            if (asyncResult.WasSuccessfull)
            {
                this.StatusMessage = &quot;New forecast received ok.&quot;;
                this.ForecastThatWasReceived = asyncResult.Result;

            }
            else
            {
                this.ForecastThatWasReceived = null;
                this.StatusMessage = &quot;Error result received: Error description: &quot; + asyncResult.Exception.Message;
            }
        }

        private IDelegateCommand getForecastCommand;

        public IDelegateCommand GetForecastCommand
        {
            get { return getForecastCommand; }
            set { getForecastCommand = value;
                this.OnPropertyChanged(&quot;GetForecastCommand&quot;);
            }
        }

        private DailyForecast forecastThatWasReceived;

        public DailyForecast ForecastThatWasReceived
        {
            get { return forecastThatWasReceived; }
            set { forecastThatWasReceived = value;
            this.OnPropertyChanged(&quot;ForecastThatWasReceived&quot;);
            }
        }

        public DateTime ValidForecastDate
        {
            get
            {
                return DateTime.Now;
            }
        }

        public DateTime BadForecastDate
        {
            get
            {
                return DateTime.MinValue;
            }
        }

        private string statusMessage;
        public string StatusMessage
        {
            get { return statusMessage; }
            set { statusMessage = value;
            this.OnPropertyChanged(&quot;StatusMessage&quot;);
            }
        }
    }
}
</pre>
<p>As you can see from the ForecastViewModel we have a command that&#8217;s invoking the web service called GetForecastCommand and we have a action method OnResultReceived that receives the result.</p>
<p>If the web service call fails we set the ForecastThatWasReceived to null and we set the StatusMessage to the Message of the Exception we received from server.</p>
<p>So here is our simple ForecastView:</p>
<pre class="brush: xml;">
&lt;UserControl x:Class=&quot;Views.ForecastView&quot;
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
    xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
    xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
    mc:Ignorable=&quot;d&quot;
    d:DesignHeight=&quot;300&quot; d:DesignWidth=&quot;400&quot; MinHeight=&quot;400&quot; MinWidth=&quot;400&quot;&gt;

    &lt;Grid x:Name=&quot;LayoutRoot&quot; Background=&quot;Red&quot;&gt;

        &lt;Grid.RowDefinitions&gt;
            &lt;RowDefinition&gt;&lt;/RowDefinition&gt;
            &lt;RowDefinition&gt;&lt;/RowDefinition&gt;
            &lt;RowDefinition&gt;&lt;/RowDefinition&gt;
        &lt;/Grid.RowDefinitions&gt;
        &lt;StackPanel Orientation=&quot;Vertical&quot; Grid.Row=&quot;0&quot;&gt;
            &lt;Button Content=&quot;Invoke valid web service call&quot; Command=&quot;{Binding GetForecastCommand}&quot; CommandParameter=&quot;{Binding ValidForecastDate}&quot; HorizontalAlignment=&quot;Center&quot; VerticalAlignment=&quot;Center&quot; Margin=&quot;10&quot; /&gt;

            &lt;Button Content=&quot;Invoke web service call that throws exception on server&quot; Command=&quot;{Binding GetForecastCommand}&quot; CommandParameter=&quot;{Binding BadForecastDate}&quot; HorizontalAlignment=&quot;Center&quot; VerticalAlignment=&quot;Center&quot; Margin=&quot;10&quot; /&gt;

        &lt;/StackPanel&gt;

        &lt;Grid Grid.Row=&quot;1&quot;&gt;
            &lt;StackPanel Orientation=&quot;Vertical&quot;&gt;
                &lt;TextBlock Text=&quot;{Binding ForecastThatWasReceived.Date, StringFormat='Date: {0}', FallbackValue=' ?'}&quot; /&gt;
                &lt;TextBlock Text=&quot;{Binding ForecastThatWasReceived.Description, StringFormat='Description: {0}', FallbackValue=' ?'}&quot; /&gt;

            &lt;/StackPanel&gt;
        &lt;/Grid&gt;

        &lt;Grid Grid.Row=&quot;2&quot;&gt;
            &lt;TextBlock Text=&quot;{Binding StatusMessage}&quot; TextWrapping=&quot;Wrap&quot; /&gt;

        &lt;/Grid&gt;

    &lt;/Grid&gt;
&lt;/UserControl&gt;
</pre>
<p>As you can see we have two buttons, each wired up to the same GetForecastCommand but with different parameters.<br />
One is sending the current date to the server and other is using the BadForecastDate databound from ViewModel which is set to DateTime.Min. When web service receives any other date then DateTime.Min it returns valid instance of DailyForecast class and if it receives DateTime.Min it throws some bogus exception.<br />
This is how we will test our WebServiceFactory class to see if it can handle the exceptions thrown on server side or not.</p>
<p>you can test the <a title="Unit Testable Web Service in MVVM and Silverlight 4 demo application" href="http://demos.roboblob.com/demos/Silverlight4/MVVM/TestableWebServices/" target="_blank">live sample application here</a>.</p>
<p>So here is screenshot of the app (in case you dont have the <a href="http://www.silverlight.net/getstarted/" target="_self">Silverlight 4 runtime</a> installed) when we invoke the web service with current date:</p>
<p><a href="http://blog.roboblob.com/wp-content/uploads/2010/04/WebServiceCallOk.jpg"><img class="aligncenter size-medium wp-image-268" title="WebServiceCallOk" src="http://blog.roboblob.com/wp-content/uploads/2010/04/WebServiceCallOk-300x248.jpg" alt="" width="300" height="248" /></a></p>
<p>As you can see when we click on first button we receive the valid forecast and when we click the second one, we will receive the error but it will be catched and wrapped in our AsyncWebServiceCallResult class and our UI won&#8217;t hang and we will be able to recover from that error and immediately invoke the web service call again with different parameters.</p>
<p>Here is the same app when we invoke the web service method with invalid (min) date so it throws exception:</p>
<p><a href="http://blog.roboblob.com/wp-content/uploads/2010/04/WebServiceCallBad.jpg"><img class="aligncenter size-medium wp-image-269" title="WebServiceCallBad" src="http://blog.roboblob.com/wp-content/uploads/2010/04/WebServiceCallBad-300x248.jpg" alt="" width="300" height="248" /></a></p>
<p>So this should help us handle the web service with greater ease right ?  <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>But wait! We are not finished yet! Those of you that were paying attention noticed i promised a unit testable web services.</p>
<p>So lets do that also.</p>
<p>We will add another SIlverlight application to our sample code and set it up with Silverlight Unit Testing Framework.</p>
<p>Also we will reference all the needed projects &#8211; ViewModels, Abstractions.Silverlight, Framework.Abstractions and Framework.Implementors.</p>
<p>Also we need to make a fake WebServiceClientFactory and IWeatherService implementations so we can use them in our tests instead of the real implementations.</p>
<p>So lets do that first. here is the FakeWebServiceClientFactory:</p>
<pre class="brush: csharp;">
using System;
using Abstractions;
using Framework.Abstractions.Silverlight.WebServices;

namespace Silverlight.Tests
{
    public class FakeWebServiceClientFactory : IWebServiceClientFactory&lt;IWeatherForecastService&gt;
    {
        public FakeWebServiceClientFactory()
        {
            this.WebServiceInstance = new FakeWeatherService();
        }

        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public IWeatherForecastService WebServiceInstance { get; private set; }

        public object LastParameterSentToInvoke;

        public object NextResultToReturn;

        public void Invoke&lt;TParam, TResult&gt;(TParam param, object state, Func&lt;TParam, AsyncCallback, object, IAsyncResult&gt; beginOp, Func&lt;IAsyncResult, TResult&gt; endOp, Action&lt;AsyncWebServiceCallResult&lt;TResult&gt;&gt; onComplete)
        {
            this.LastParameterSentToInvoke = param;

            var nextResult = NextResultToReturn as AsyncWebServiceCallResult&lt;TResult&gt;;

            if (nextResult != null)
            {
                onComplete(nextResult);
            }
            else
            {
                onComplete(new AsyncWebServiceCallResult&lt;TResult&gt;
                               {Exception = new Exception(&quot;Some exception&quot;), WasSuccessfull = false});
            }
        }
    }
}
</pre>
<p>As you can see it does not do much, its just a manually written mock class we can use in our test instead of the real web service client factory.<br />
It allows us to check what was sent to the Invoke method as parameter and it allows us to set what will be sent to the OnComplete handler when client code invokes some web service call.</p>
<p>Also we need a stub for the IWeatherForecastService so here it is:</p>
<pre class="brush: csharp;">
using System;
using Abstractions;

namespace Silverlight.Tests
{
    public class FakeWeatherService : IWeatherForecastService
    {
        public IAsyncResult BeginGetForecast(DateTime day, AsyncCallback callback, object state)
        {
            throw new NotImplementedException();
        }

        public DailyForecast EndGetForecast(IAsyncResult result)
        {
            throw new NotImplementedException();
        }
    }
}
</pre>
<p>Again its very simple its just a Stub class that allows us to instantiate and use it without really calling it.<br />
So now we can write few tests for our ForecastViewModel:</p>
<pre class="brush: csharp;">
using System;
using Abstractions;
using Framework.Abstractions.Silverlight.WebServices;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ViewModels;

namespace Silverlight.Tests
{
    [TestClass]
    public class ForecastViewModelTests
    {
        [TestMethod]
        public void GetForecastCommand_WhenExecutedWithParam_InvokesCallOnWebServiceClientFactoryInstance()
        {
            var fakeFactory = new FakeWebServiceClientFactory();
            var viewModel = new ForecastViewModel(fakeFactory);

            var date = DateTime.Now;

            viewModel.GetForecastCommand.Execute(date);

            Assert.AreEqual(date, fakeFactory.LastParameterSentToInvoke);
        }

        [TestMethod]
        public void GetForecastCommand_WhenExecutedWithMinDateANdWebserviceReturnsUnsuccessfullResult_SetsTheForecastThatWasReceivedToNull()
        {
            var fakeFactory = new FakeWebServiceClientFactory();
            var viewModel = new ForecastViewModel(fakeFactory);
            viewModel.ForecastThatWasReceived = new DailyForecast() {Description = &quot;just dummy so we can test if it was set to null.&quot;};

            fakeFactory.NextResultToReturn = new AsyncWebServiceCallResult&lt;DailyForecast&gt;() {WasSuccessfull = false, Exception = new Exception(&quot;Bad error.&quot;)};
            viewModel.GetForecastCommand.Execute(DateTime.MinValue);

            Assert.IsNull(viewModel.ForecastThatWasReceived);
        }

        [TestMethod]
        public void GetForecastCommand_WhenExecutedWithMinDateANdWebserviceReturnsUnsuccessfullResult_SetsTheStatusMessageToErrorFromReturnedException()
        {
            var fakeFactory = new FakeWebServiceClientFactory();
            var viewModel = new ForecastViewModel(fakeFactory);
            viewModel.ForecastThatWasReceived = new DailyForecast() { Description = &quot;just dummy so we can test if it was set to null.&quot; };

            fakeFactory.NextResultToReturn = new AsyncWebServiceCallResult&lt;DailyForecast&gt;() { WasSuccessfull = false, Exception = new Exception(&quot;Bad error.&quot;) };
            viewModel.GetForecastCommand.Execute(DateTime.MinValue);

            Assert.IsTrue(viewModel.StatusMessage.Contains(&quot;Bad error.&quot;));
        }

        [TestMethod]
        public void GetForecastCommand_WhenExecutedWithOkDateANdWebserviceReturnsSuccessfullResult_SetsTheStatusMessageToOkMessage()
        {
            var fakeFactory = new FakeWebServiceClientFactory();
            var viewModel = new ForecastViewModel(fakeFactory);
            viewModel.ForecastThatWasReceived = null;

            fakeFactory.NextResultToReturn = new AsyncWebServiceCallResult&lt;DailyForecast&gt;() { WasSuccessfull = true};
            viewModel.GetForecastCommand.Execute(DateTime.Now);

            Assert.IsTrue(viewModel.StatusMessage.Contains(&quot;New forecast received ok.&quot;));
        }

    }
}
</pre>
<p>And when we run them, as you can see from the screenshot below, they are all <span style="color: #008000;">GREEN!</span></p>
<p><span style="color: #008000;"><a href="http://blog.roboblob.com/wp-content/uploads/2010/04/AllTestsAreGreenAndTheWorldIsSafeAgain.jpg"><img class="aligncenter size-medium wp-image-271" title="AllTestsAreGreenAndTheWorldIsSafeAgain" src="http://blog.roboblob.com/wp-content/uploads/2010/04/AllTestsAreGreenAndTheWorldIsSafeAgain-300x178.jpg" alt="" width="300" height="178" /></a></span></p>
<p><span style="color: #008000;"><span style="color: #000000;">So there you go, we have completed in this lengthy posts most of the tasks we set in the beginning. Off course there are many places for improvement but the basis of a simple way to invoke WCF web services from Silverlight and MVVM and Unit Testability are there.</span></span></p>
<p><span style="color: #008000;"><span style="color: #000000;">If you have some comments and improvements to the solutions presented here i would be happy to hear them out.</span></span></p>
<p><span style="color: #008000;"><span style="color: #000000;">You can <a title="Unit Testable Web Service in MVVM and Silverlight 4 Solution Visual Studio 2010" href="http://demos.roboblob.com/demos/Silverlight4/MVVM/TestableWebServices/TestableWebServicesInMVVMSilverlight4Solution.zip" target="_self">download Visual Studio 2010 Solution</a> with the code from this post if you want to run it locally.<br />
</span></span></p>
<p><span style="color: #008000;"><span style="color: #000000;">Until then, happy testing!<br />
</span></span></p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F&amp;title=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F&amp;title=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F&amp;title=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F&amp;headline=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4&amp;u=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F&amp;title=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4&amp;summary=&amp;source=" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://blog.roboblob.com/2010/04/11/unit-testable-wcf-web-services-in-mvvm-and-silverlight-4/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Unit testing and mocking internal interfaces with RhinoMocks</title>
		<link>http://blog.roboblob.com/2010/02/18/unit-testing-and-mocking-internal-interfaces-with-rhinomocks/</link>
		<comments>http://blog.roboblob.com/2010/02/18/unit-testing-and-mocking-internal-interfaces-with-rhinomocks/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 21:48:07 +0000</pubDate>
		<dc:creator>roboblob</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Mocking]]></category>
		<category><![CDATA[Mocks]]></category>
		<category><![CDATA[RhinoMocks]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://blog.roboblob.com/?p=234</guid>
		<description><![CDATA[Im not the kind of purist that will avoid unit testing internal classes. If its some very important code i want to test it even if its internal.

Another case when i want to access internal classes is when i want to test some public class that uses some internal classes (via their interfaces).
In this scenario i need to be able to mock those internal interfaces that the public class is using in order to be able to instantiate it and unit test it.]]></description>
			<content:encoded><![CDATA[Number of View: 2289<br/><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Im working on a project that i want to cover with unit tests as much as possible.</p>
<p>Problem is that most of the things i need to test are kept internal inside some libraries.</p>
<p>Im not the kind of purist that will avoid unit testing internal classes. If its some very important code i want to test it even if its internal.</p>
<p>Another case when i want to access internal classes is when i want to test some public class that uses some internal classes (via their interfaces).<br />
In this scenario i need to be able to mock those internal interfaces that the public class is using in order to be able to instantiate it and unit test it.</p>
<p>Now some of you experienced TDD people will shout: &#8220;Ha haaa that&#8217;s easy just use the</p>
<p>[assembly: InternalsVisibleTo("Some.TestAssembly.Name")] and your are cool&#8221;.</p>
<p>But this is only partial true. Here is why:<br />
Using the InternalsVisibleTo attribute will allow you to access internal members of assembly from the test assembly and use them in unit tests, but if you try to mock them (lets say we use the fantastic <a href="http://www.ayende.com/projects/rhino-mocks.aspx" target="_blank">RhinoMocks</a>), you will get exception similar to this one:</p>
<p><span style="color: #ff0000;">Castle.DynamicProxy.Generators.GeneratorException: Type is not public, so a proxy cannot be generated. </span></p>
<p><span style="color: #ff0000;">Type: Roboblob.Implementors.Interfaces.ICookieService</span></p>
<p>So in this concrete case I have added the <strong>InternalsVisibleTo </strong>attribute to my main assembly and this allowed the other assembly where my unit tests are to access the internal interface ICookieService but this helped me only half-way. I forgot about RhinoMocks!.</p>
<p>So RhinoMocks cannot create proxy that implements this interface in order to create a mock and throws this exception.</p>
<p>I tried few things to solve this and then i found this link: <a href="http://ayende.com/Wiki/Rhino+Mocks+-+Internal+Methods.ashx" target="_blank">Rhino Mocks Internal Members</a>.</p>
<p>As most things in life, its very simple once you figure it out: In order to be able to mock internal members of some class you need to allow the RhinoMocks to &#8216;see&#8217; internals of this class by placing this in your AssemblyInfo.cs:</p>
<pre class="brush: csharp;">
[assembly: InternalsVisibleTo (&quot;DynamicProxyGenAssembly2&quot;)]
</pre>
<p>Since RhinoMocks must create a proxy class to create a mock and definition for that proxy is in DynamicProxyGenAssembly2 &#8211; we need to allow this assembly to access internal members of the assembly holding the class we are testing.</p>
<p>So with this new trick I&#8217;m ready to dive into my mocking adventures&#8230;.</p>
<p>Wish me luck <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F&amp;title=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F&amp;title=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F&amp;title=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F&amp;headline=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks&amp;u=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F&amp;title=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks&amp;summary=&amp;source=" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://blog.roboblob.com/2010/02/18/unit-testing-and-mocking-internal-interfaces-with-rhinomocks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
