Unit testing a viewmodel

Topics: Prism v4 - WPF 4
Mar 6, 2012 at 3:10 PM

I admit this now - I'm doing this backwards in that the application has been written before the unit tests ;) (I have, of course, slapped my own wrists for doing it that way!)

The issue I'm facing is that I have a view model that calls a WCF service to return some data which is bound to a grid in the view.  I've mocked up some data, but as soon as I try to get at my viewmodel to do something with it it rolls over and doesn't even get close to waving a white flag before it dies horribly!

My view models resemble the ones in here http://www.codeproject.com/Articles/165370/Creating-View-Switching-Applications-with-Prism-4 in that my constructor for them calls an intialise method that hooks up commands and uses the event aggregator and service locator, and I'm beginning to think that the viewmodels are not setup correctly,

 

Snippet from viewmodel 

   /// <summary>
        /// Default constructor.
        /// </summary>
        public ModuleAppMatterManagementViewModel()
        {
            this.Initialize();
        }

   /// <summary>
        /// Initializes the view model.
        /// </summary>
        private void Initialize()
        {
            // Initialize command properties
            this.Command1= new Command1Command(this);


            // Initialize administrative properties
            this.IsChecked = false;

            // Subscribe to Composite Presentation Events
            var eventAggregator = ServiceLocator.Current.GetInstance<IEventAggregator>();
            var navigationCompletedEvent = eventAggregator.GetEvent<NavigationCompletedEvent>();
            navigationCompletedEvent.Subscribe(OnNavigationCompleted, ThreadOption.UIThread);

// code to connect to WCF service and bind data to grid goes here

}          
snippet from test class

[TestMethod]
        public void TestViewMatters()
        {



            List<TestMatter> matters = new List<TestMatter>();
            matters.Add(TestMatter.CreateMatter(1, "open"));
            matters.Add(TestMatter.CreateMatter(2, "open"));
            matters.Add(TestMatter.CreateMatter(3, "open"));
            matters.Add(TestMatter.CreateMatter(4, "open"));
            
            //code falls over at the line below
            MatterManagementViewModel target = new MatterManagementViewModel();

           //do stuff with viewmodel and assertions go here

       

    } 
Does anyone have any thoughts????

Developer
Mar 6, 2012 at 4:49 PM
Edited Mar 6, 2012 at 4:49 PM

Hi,

Based on my understanding, when testing an application, the usual approach is to mock all the dependencies required by the element being tested. This includes the WCF service, not only the data.

I couldn't find why the view model fails when tested in the code snippets provided above. However, if your view model obtains the WCF service through the service locator doing something like this:

IWcfService service = ServiceLocator.Current.GetInstance<IWcfService>();

Then you should, in the test method, be able to register a mocked service in the container using the same interface. When retrieving the service, the view model will receive the mocked service instead.

As a side note, I believe you could find the unit tests included in the QuickStarts and Reference Implementation provided by Prism useful, as a base to understand how Prism applications are tested.

I hope you find this useful,

Damian Cherubini
http://blogs.southworks.net/dcherubini