How to mock the call to Dispatcher.BeginInvoke?

1,374 views
Skip to first unread message

Sandeep Gupta

unread,
Jan 16, 2014, 8:38:32 AM1/16/14
to nsubs...@googlegroups.com
Hi,

In one of my NSubstitute unit test, i have a target class.
I face a problem in no. of cases similar to the code below in the target class:
=======================================================================
        public void _UpdateChecklistStatus(object checklistViewModel)
        {

                                          
                OnCompletion<List<object>> updateChecklistStatusCallback = (result, ex) =>
                                                    {

                                                          if (result != null && result[0] != null && result[0] is bool)                                                           {
Dispatcher.BeginInvoke(new Action(() =>                                                                               {                                                                                    if (updateResult == false)                                                                                    {                                                                                     //some code to execute
}
}
}


m_ObjectManager.UpdateDataAsync(new ChecklistDataModel(), OperationType.SaveSingle, new CacheSettings(), updateChecklistStatusCallback, updateChecklistStatuskParam, Constants.PROFILE_UPDATE_CHECKLIST_STATUS);
}  
=======================================================================

I have mocked the object "m_ObjectManager" that calls(asynchronous) a WCF service through "UpdateDataAsync"  and calls back the callback "updateChecklistStatusCallback" with the valid result which is also mocked.
Now the issue is after mocking (m_ObjectManager.UpdateDataAsync) i get the callback into "updateChecklistStatusCallback"  but the code within "Dispatcher.BeginInvoke" never gets executed.
"Disptacher" is System.Windows.Threading. 
I have placed the breakpoints at several places within "Dispatcher.BegingInvoke" block but none of them got hit and the unit test completed successfully.
Can someone please help me on what to do about it?Is there any way to mock it or something else?

Eagerly awaiting the responses!

Thanks,
Sandeep                                    

David Tchepak

unread,
Jan 20, 2014, 4:35:06 PM1/20/14
to nsubs...@googlegroups.com
Hi Sandeep,

Can you show how you have mocked m_ObjectManager? Substitutes will not automatically invoke callbacks unless you have explicitly set up the sub's call to do so.
There is some information on invoking callbacks here: http://nsubstitute.github.io/help/actions-with-arguments/

You may also want to inject a fake dispatcher into the target class to remove variability due to threading.

Regards,
David




--
You received this message because you are subscribed to the Google Groups "NSubstitute" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nsubstitute...@googlegroups.com.
To post to this group, send email to nsubs...@googlegroups.com.
Visit this group at http://groups.google.com/group/nsubstitute.
For more options, visit https://groups.google.com/groups/opt_out.

Sandeep Gupta

unread,
Feb 4, 2014, 4:33:30 AM2/4/14
to nsubs...@googlegroups.com
Hi David,

Thank you for your response.
Could you please show how to inject a "Dispatcher" into the target class?

m_ObjectManager is an object of "IObjectManager" resides within the target class.
I have exposed a setter(ObjectManager) into the same

And in the test class i have done similar to:

_objectManager=Substitute.For<IObjectManager>;
_target.ObjectManager=_objectManager;

Thanks,
Sandeep

David Tchepak

unread,
Feb 4, 2014, 7:41:37 PM2/4/14
to nsubs...@googlegroups.com
To inject the Dispatcher we first need to wrap it. Then we can expose a setter or add a constructor parameter to get instances into the target class.

```
public interface IDispatcher {
  void Dispatch(Action action);
}
public class RealDispatcher : IDispatcher {
  public void Dispatch(Action action) { Dispatcher.BeginInvoke(action); }
}
```

Now in the target class:

```
public class TargetClass {
  IDispatcher dispatcher = new RealDispatcher(); // add setter for this, or initialise from constructor param
  public void _UpdateChecklistStatus(object checklistViewModel)
  {
     /* ... snip ... */
      dispatcher.BeginInvoke(new Action(() => {
                            if (updateResult == false)
                            {
                              //some code to execute
                            }
      });
    /* ... snip ... */
}
```

You can now mock the dispatcher used in the target class, or replace it with a fake implementation that runs the action synchronously.

Hope this helps.
Regards,
David

Reply all
Reply to author
Forward
0 new messages