Testing Lazy Loading in Silverlight

Testing Lazy Loading in Silverlight

Old forum URL: forums.lhotka.net/forums/t/9257.aspx


Smith866 posted on Thursday, July 22, 2010

Hi,

I am currently developing a system using CSLA 4 and Silverlight.  I am also developing a suite of tests (arguably unit tests :).  I am using the UnitDriven framework to help test the asynchronous pieces, and this works very well (Thanks Rocky!)

Now I am looking at lazy loading my child objects in the manner described by Rocky's recent blog post.  The problem I now have is how can I perform unit tests against objects whose properties are being lazy loaded asynchronously?  It is easy to unit test the asynchronous factory methods because I can pass my own handler to those functions.  With the properties, I can only call the getter...I can't pass a handler.

Has anybody else encountered this issue?  Is there a good way to test this?  I can see one option would be for my calling thread to simply block and wait for the IsBusy property to become false again.  The issue there is if I hit multiple lazy loaded children, how do I know when each one has finished?  Do you this might work or is there a better way?

P.S.  I believe that this same issue needs to be solved for testing ViewModels as well, as the ViewModel can call a method such as BeginRefresh, but there isn't a way (that I can see) to pass a handler...it looks like the ViewModel handles the callback itself.

Any advice would be greatly appreciated!

 

RockfordLhotka replied on Thursday, July 22, 2010

There are different async models in .NET in general - the old Begin/End method model, the event model and the callback model.

Recently the callback model has become popular, but the event model is usually a parallel offering. The Begin/End model seems to have lost favor.

In short, where a callback model isn't available, the event model is the way to go.

You should be able to trigger off PropertyChanged though, not necessarily BusyChanged - PropertyChanged should be raised when the property is set (that's how data binding knows to refresh for example).

The same is true for a ViewModel<T> - there's a PropertyChanged on the Model property that triggers data binding, and that should work for your test as well.

In any realistic sense, your test should trigger off the same things the UI would trigger off - otherwise your test doesn't mirror real-world usage very well.

Smith866 replied on Tuesday, August 03, 2010

Hi Rocky,

Sorry for the slow response, but I'm just now getting down to implementing this.  I can't seem to see any Model changes when I subscribe to the PropertyChanged event of the ViewModel<T>.  I see things like IsBusy, CanSave, CanCancel firing this event, but nothing related to the Model.  Did I miss something?

I had a look in ViewModelBase, and I noticed that the setters of many of these properties (IsBusy, CanSave, CanCancel) call the OnPropertyChanged method.  If I modify the Model's setter by adding the following line:  OnPropertyChanged("Model");  I get the functionality I need...I get notification when the Model changes.

Should there in fact be a call to OnPropertyChanged in the Model's setter, or have I just misunderstood the technique I should be using to subscribe to model changing events?

 

RockfordLhotka replied on Tuesday, August 03, 2010

The Model property is a dependency property, so PropertyChanged is (or should be) automatically raised when it is changed.

Smith866 replied on Wednesday, August 04, 2010

I'm not seeing this functionality.  Once my ViewModel has loaded it's Model I can then catch the PropertyChanged event to watch for any of the Model's children being lazy loaded asynchronously, but I can't catch the original "Model is now loaded into the viewmodel" event (without my modification mentioned above).

Could you perhaps provide a code sample?  I'm thinking that if I were using WPF instead of Silverlight, I could use the DependencyPropertyDescriptor.AddValueChanged, but this doesn't exist in Silverlight.

artsd replied on Wednesday, December 01, 2010

I am experiencing the same problem. Did you ever find a solution besides manually raising a property changed for "Model"?

edit:

In my View-Model base class (which derives from ViewModel<T>), I overrode OnModelChanged() and raised the property changed for "Model" there after calling base.OnModelChanged().

 

 

 

 

 

 

 

 

 

Smith866 replied on Wednesday, December 01, 2010

Well, sort of  :)

For a number of reasons I ended up needing to create my own ViewModel that inherits from ViewModel<T> and implements a few interfaces.  In my implementation, I have added a few events.  One of the events that I added was a "Model Changed" event.  In my tests, I can now just wire up this "Model Changed" event and handle it quite easily.  

Copyright (c) Marimer LLC