Tho*_*ock 9 .net c# unit-testing asynchronous
[单位测试新手] [c#]
请考虑以下情形:
我正在使用Silverlight并调用WCF服务.Silverlight只能异步调用WCF服务.我构建了一个围绕WCF服务的包装器,以便我可以使用Action参数.(使客户端代码更清洁).
所以我有一个异步服务来检索会议室.
public interface IMeetingRoomService
{
void GetRooms(Action<List<MeetingRoom>> result);
}
Run Code Online (Sandbox Code Playgroud)
转换GetRooms List<MeetingRoom> GetRooms()不是一个选择.
我想在ViewModel中使用此服务来设置名为Rooms的公共属性.
public class SomeViewModel
{
private readonly IMeetingRoomService _meetingRoomService;
public List<MeetingRoom> Rooms { get; set; }
public SomeViewModel(IMeetingRoomService meetingRoomService)
{
this._meetingRoomService = meetingRoomService;
}
public void GetRooms()
{
// Code that calls the service and sets this.Rooms
_meetingRoomService.GetRooms(result => Rooms = result);
}
}
Run Code Online (Sandbox Code Playgroud)
我想单元测试SomeViewModel.GetRooms()的实现.(对于这个问题,我很快写了实现,但实际上我正在尝试使用TDD.)
我该如何完成此测试?我正在使用NUnit和Moq.
[Test]
public void GetRooms_ShouldSetRooms()
{
var theRooms = new List<MeetingRoom>
{
new MeetingRoom(1, "some room"),
new MeetingRoom(2, "some other room"),
};
var meetingRoomService = new Mock<IMeetingRoomService>();
//How do I setup meetingRoomService so that it gives theRooms in the Action??
var viewModel = new SomeViewModel(meetingRoomService.Object);
viewModel.GetRooms();
Assert.AreEqual(theRooms, viewModel .Rooms);
}
Run Code Online (Sandbox Code Playgroud)
编辑:
解
首先阅读Stephane的回答.
这是测试代码我最后写的感谢stephane的答案:
[Test]
public void GetRooms_ShouldSetRooms()
{
var meetingRoomService = new Mock<IMeetingRoomService>();
var shell = new ShellViewModel(meetingRoomService.Object);
var theRooms = new List<MeetingRoom>
{
new MeetingRoom(1, "some room"),
new MeetingRoom(2, "some other room"),
};
meetingRoomService
.Setup(service => service.GetRooms(It.IsAny<Action<List<MeetingRoom>>>()))
.Callback((Action<List<MeetingRoom>> action) => action(theRooms));
shell.GetRooms();
Assert.AreEqual(theRooms, shell.Rooms);
}
Run Code Online (Sandbox Code Playgroud)
Sté*_*ane 12
这是一些伪代码,我还没有运行它.但我认为这就是你想要的.
SetupCallback是你感兴趣的.
对于_meetingRoomServiceFake.GetRooms的所有调用,只需将_getRoomsCallback设置为传入的参数即可.
您现在可以引用要在viewmodel中传递的回调,并且可以使用要测试它的MeetingRoom列表来调用它.因此,您可以像验证同步代码一样测试异步代码.设置假货只是一个更多的仪式.
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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7367 次 |
| 最近记录: |