How to mock RegionManager.RequestNavigate

Topics: Prism v4 - Silverlight 4
Jul 2, 2011 at 5:41 AM


I can't mock the RequestNavigate method in RegionManager because it's an extension method. I want my unit test to verify that the region manager was called and that the correct Uri was passed to it.  Is there some way to mock the RequestNavigate method (or some other clever way to verify that the method is called with the correct parameters)?



Jul 4, 2011 at 4:33 AM


WHy would you want to mck requestnavigate? All you need to verify is the url you are passing to it right?

Jul 4, 2011 at 6:12 AM

In most cases I want to know that a method has made a navigation call and that the Uri for that call is correct.  Here's a simple example:

        public void OnAdd(object parameter)
            var uriQuery = new UriQuery { { "Id", "0" } };
            _regionManager.RequestNavigate(RegionNames.ContentRegion, new Uri("UserDetailView" + uriQuery, UriKind.Relative));

Where _regionManager is passed in the constructor via DI.  I'm using Rhino Mocks to mock this out and want to do an AssertWasCalled on _regionManager.RequestNavigate to ensure that the OnAdd method is correct.  In other methods there are sometimes conditions around whether the navigation occurs and what the Uri querystring contains, so unit tests are even more important.  An example test for this (which doesn't work because RequestNavigation is an extension) might be:

        [Test, NUnit.Framework.Category("ViewModel")]
        public void OnAddCallsRegionManager()
            // initialise
            IRegionManager _regionManager = MockRepository.GenerateStub<IRegionManager>();
            _regionManager.Expect(r => r.RequestNavigate(Arg<string>.Is.Anything, Arg<Uri>.Is.Anything));

            Container.RegisterType<IUserListViewModel, UserListViewModel>();
            _userListViewModel = Container.Resolve<IUserListViewModel>();

            // setup
            var uriQuery = new UriQuery { { "Id", "0" } };
            var uri = new Uri("UserDetailView" + uriQuery, UriKind.Relative);

            // system under test

            // assertions		
            _regionManager.AssertWasCalled(r => r.RequestNavigate(

Jul 4, 2011 at 6:16 AM

In this case rather than trying to mock requestnavigate I would check if the view which you navigate to in the OnAdd is loaded into the regionmanager as a ActiveView and also if that views viewmodel received the parameter you have passed in the uriQuery. That way you are sure that the right view with the right parameter was loaded in the OnAdd method of yours.

I dont think there is a need to mock the request navigate here.

Jul 4, 2011 at 6:33 AM

I'm a little confused here (I might be misunderstanding your solution).  I'm trying to unit test my OnAdd method in isolation.  I have other tests for the OnNavigateTo method for any responding viewmodel (also isolated, so no knowledge of the requesting viewmodel).  I don't see why I should call the OnAdd method on one viewmodel and then test the result on another viewmodel and also have a view participating in this as well, not to mention all the Regionmanager stuff underneath it.  I don't think I should be testing whether the RegionManager is doing the right thing (I assume the Prism framework is doing things correctly), e.g. I shouldn't have to test that the parameter I passed into the navigation request came out the other end.  That's implicit in the way the RegionManager works.

I have come up with a workaround, but suspect it's likely to be frowned on here.  I've created a wrapper interface and class for RegionManager (just for the RequestNavigate method) and I pass that into any viewmodel that has to navigate to another view.  Doing this actually allows me to run the exact test above, verifying the address being navigated to and the parameter being passed.  So I think I'm good for now.

Thanks for your help anyway.


Jul 4, 2011 at 6:39 AM

That is precisely what I asked in the begining. Why would you want to mock requestnavigate? It's part of the prism framework and it should work just fine. What you need to test is if the right view was with right parameter, which is represented by the uri, is called.

Creating a wrapper class around regionmanager, like a navigation service, which accepts the url and does the request navigate, is just fine I think. Even in our project we navigate around using a service class which does the actual navigation within the region.

Jul 4, 2011 at 7:29 AM

Ok. Perhaps I should have said I wanted to stub out the RegionManager, rather than mock it.  Sorry for the confusion.