Mocking method with Action parameter

后端 未结 2 591
陌清茗
陌清茗 2021-01-11 21:09

[unit testing newbie] [c#]

Consider the following scenario:

I\'m using Silverlight and calling a WCF service. Silverlight can only call WCF services

相关标签:
2条回答
  • 2021-01-11 21:26

    Here is some pseudo code, I haven't run it. But I think that's what you want.

    SetupCallback is what you are interested in.

    For all the calls to _meetingRoomServiceFake.GetRooms, simply set the _getRoomsCallback to the parameter passed in.

    You now have a reference to the callback that you are passing in your viewmodel, and you can call it with whatever list of MeetingRooms you want to test it. So you can test your asynchronous code almost the same way as synchronous code. it's just a bit more ceremony to setup the fake.

    Action<List<MeetingRoom>> _getRoomsCallback = null;
    IMeetingRoomService _meetingRoomServiceFake;
    
    
    private void SetupCallback()
    {
         Mock.Get(_meetingRoomServiceFake)
             .Setup(f => f.GetRooms(It.IsAny<Action<List<MeetingRoom>>>()))
             .Callback((Action<List<MeetingRoom>> cb) => _getRoomsCallback= cb);
    }
    
    [Setup]
    public void Setup()
    {
         _meetingRoomServiceFake = Mock.Of<IMeetingRoomService>();
         SetupCallback();
    }
    
    [Test]
    public void Test()
    {
    
          var viewModel = new SomeViewModel(_meetingRoomServiceFake)
    
          //in there the mock gets called and sets the _getRoomsCallback field.
          viewModel.GetRooms();
          var theRooms = new List<MeetingRoom>
                       {
                           new MeetingRoom(1, "some room"),
                           new MeetingRoom(2, "some other room"),
                       };
    
         //this will call whatever was passed as callback in your viewModel.
         _getRoomsCallback(theRooms);
    }
    
    0 讨论(0)
  • You could use an AutoResetEvent to handle async calls.

    Just initialize it as unset and configure your mock service to set it in the callback. (IE: var mockService = new Mock(); mockService.SetUp(x => x.MyMethod()).Returns(someStuff).Callback(() => handle.Set()); )

    After that I use hadle.WaitOne(1000) to check if it was called. (IMHO 1000 miliseconds are more than enough to run the async code).

    Sorry: This was supposed to go as a reply to the post above... I can't for the life of me figure out how to reply :)

    0 讨论(0)
提交回复
热议问题