Using RequestDispactherStub to test viewmodel results in an error -- Requests where already send. Either add request earlier or call Clear.

74 views
Skip to first unread message

jackjones

unread,
Aug 31, 2012, 6:43:32 AM8/31/12
to agath...@googlegroups.com
Hi,

I think that I am doing something obviously wrong here but I am not sure exactly what it is despite lots of digging so I'm looking for some help.

I have a test like this where I am sending in the RequestDispatcherFactoryStub
        
        [Test]
        public void Remove_LocationType_From_List()
        {
            //Arrange
            RequestDispatcherStub.AddResponsesToReturn(new GetAllLocationTypesResponse { LocationTypes = _locationTypes },
                new RemoveLocationTypeResponse { Success = true });

            var viewLocatorService = new Mock<IViewLocatorService>();
            var eventAggregator = new Mock<IEventAggregator>();
            var locationTypeListViewModel = new LocationTypesListViewModel(eventAggregator.Object, RequestDispatcherFactoryStub, viewLocatorService.Object);
            locationTypeListViewModel.SelectedLocationType = locationTypeListViewModel.AllLocationTypes[1];
            
            //Act
            locationTypeListViewModel.DeleteLocationTypeCommand.Execute();
            
            //Assert
            Assert.AreEqual(locationTypeListViewModel.AllLocationTypes.Count, 2);
        }

then in the view model I have a call to send the request to Agatha which essentially looks like this 

        protected virtual T SendMessageToAgatha<T>(Request request) where T : Response
        {
            var response = RequestDispatcherFactory.CreateRequestDispatcher().Get<T>(request);
            return response;
        }

However when the RequestDispatcherFactory.CreateRequestDispatcher() call is made I get the following error :- System.InvalidOperationException : Requests where already send. Either add request earlier or call Clear.

Any ideas what I am doing wrong? Any help would be much appreciated. Many thanks in advance

Davy Brion

unread,
Aug 31, 2012, 7:19:48 AM8/31/12
to agath...@googlegroups.com
the RequestDispatcherFactoryStub implementation of IRequestDispatcherFactory always returns the same instance:

the RequestDispatcher can't be used to send subsequent requests unless you speficially call the .Clear method, that's where the exception is coming from

btw, your test indicates that you're returning two responses, but your SendMessageToAgatha method sends each request separately and immediately, which negates the batching benefits of Agatha

jackjones

unread,
Aug 31, 2012, 7:34:50 AM8/31/12
to agath...@googlegroups.com
Hi and thanks for the response - I will look into the batching side of things,

Based on the error message I have tried putting Clear() in various different places but with no success. There is a call to SendMessageToAgatha in the view model constructor and also one in the DeleteLocationTypeCommand method.
If I change the code as below I still get the same error. Is that what you meant with regards to calling Clear()?

        [Test]
        public void Can_Remove_LocationType_From_List()
        {
            //Arrange
            RequestDispatcherStub.AddResponseToReturn(new GetAllLocationTypesResponse { LocationTypes = _locationTypes });
            var viewLocatorService = new Mock<IViewLocatorService>();
            var eventAggregator = new Mock<IEventAggregator>();
            var locationTypeListViewModel = new LocationTypesListViewModel(eventAggregator.Object, RequestDispatcherFactoryStub, viewLocatorService.Object);
            locationTypeListViewModel.SelectedLocationType = locationTypeListViewModel.AllLocationTypes[1];
            RequestDispatcherStub.Clear();
            RequestDispatcherStub.AddResponseToReturn(new RemoveLocationTypeResponse { Success = true });        

Davy Brion

unread,
Aug 31, 2012, 7:59:51 AM8/31/12
to agath...@googlegroups.com
no, Clear should be called in general whenever you want to issue 2 service calls with the same RequestDispatcher instance

the code that you are testing is initiating two service calls through your SendMessageToAgatha method, which causes the problem. You either need an IRequestDispatcherFactory implementation that returns a new instance of RequestDispatcherStub whenever CreateRequestDispatcher is called, which will be cumbersome because you'll need to access each of those stubs in your tests, or change the way you're using the RequestDispatcher so you can either batch the requests, or call the .Clear method on the RequestDispatcher if you're using the same instance for multiple service calls.

Is this in a web or winforms/wpf context? i'm assuming it's some sort of winforms/wpf MVVM-like thingy due to the ViewModel initiating service calls (in which case, this may interest you: http://davybrion.com/blog/2010/07/the-mvvm-pattern-is-highly-overrated/).  If you're not in a web context, you might be better off with the AsyncRequestDispatcher and its factory.   

either way, i recommend reading the following pages to get a better grasp on how the dispatchers work and how they're meant to be used:

jackjones

unread,
Sep 4, 2012, 7:56:59 AM9/4/12
to agath...@googlegroups.com
Once again thanks for your help and I thought it appropriate to update on my progress. 

I have managed to get somewhere now. The application itself is a desktop based MVVM WPF one.
I was a regular reader of your blog so I have already seen that article and whilst I agree with it to a large extent I am not position to be able to change it at the moment.

In terms of my problem I tried and tried to use the RequestDispatcherStub Clear() methof but I could not get it to work - the Requests where already send error kept coming back. 

I'm not sure if it's related but in the code the Clear method looks like this.

 public override void Clear()
    {
        // this Stub can't clear the state because we have to be able to inspect the sent requests
        // during our tests
    }

In the end, I took your advice and changed it over to use AsyncRequestDispatcher and its factory. This now allows me to run the test successfully and appears to be working so I am quite happy.
Reply all
Reply to author
Forward
0 new messages