Mocking generic WCF ClientChannelWrapper async calls
我最近开发了一个Silverlight应用程序,该应用程序使用Mark J Millers
这是接口:
1 2 3 4 5 6 7 | public interface IClientChannelWrapper< T > where T : class { IAsyncResult BeginInvoke(Func<T, IAsyncResult> function); void Dispose(); void EndInvoke(Action< T > action); TResult EndInvoke<TResult>(Func<T, TResult> function); } |
package器基本上采用通用的异步服务接口(可能由slsvcutil生成或在WCF
典型用法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public WelcomeViewModel(IClientChannelWrapper<IMyWCFAsyncService> service) { this.service = service; this.synchronizationContext = SynchronizationContext.Current ?? new SynchronizationContext(); this.isBusy = true; this.service.BeginInvoke(m => m.BeginGetCurrentUser(new AsyncCallback(EndGetCurrentUser), null)); } private void EndGetCurrentUser(IAsyncResult result) { string strResult =""; service.EndInvoke(m => strResult = m.EndGetCurrentUser(result)); this.synchronizationContext.Send( s => { this.CurrentUserName = strResult; this.isBusy = false; }, null); } |
一切正常,但是现在我想对使用
我已经使用Moq建立了一个简单的单元测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 | [TestMethod] public void WhenCreated_ThenRequestUserName() { var serviceMock = new Mock<IClientChannelWrapper<IMyWCFAsyncService>>(); var requested = false; //the following throws an exception serviceMock.Setup(svc => svc.BeginInvoke(p => p.BeginGetCurrentUser(It.IsAny<AsyncCallback>(), null))).Callback(() => requested = true); var viewModel = new ViewModels.WelcomeViewModel(serviceMock.Object); Assert.IsTrue(requested); } |
我收到NotSupportedException:
Unsupported expression: p => p.BeginGetCurrentUser(IsAny(), null).
我对Moq还是很陌生,但是我猜想
很抱歉回答我自己的问题,但我终于明白了。
详细信息如下:
通常,该解决方案就在我眼前,因为它在Mark J Millers的IClientChannelWrapper具体实现中。在其中,他提供了两个构造函数,一个构造函数接受一串WCF端点名称(我在生产代码中使用了该字符串),第二个构造函数:
1 2 3 4 | public ClientChannelWrapper(T service) { m_Service = service; } |
事不宜迟,这是我的新测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 | [TestMethod] public void WhenCreated_ThenRequestUserName() { var IMySvcMock = new Mock<IMyWCFAsyncService>(); var serviceMock = new ClientChannelWrapper<IMyWCFAsyncService>(IMySvcMock.Object); var requested = false; IMySvcMock.Setup(svc => svc.BeginGetCurrentUser(It.IsAny<AsyncCallback>(), null)).Callback(() => requested = true); var viewModel = new ViewModels.WelcomeViewModel(serviceMock); Assert.IsTrue(requested); } |
因此,我基本上忽略了ChannelWrapper的接口,并使用WCF服务接口的Mock Object创建了该接口的新实例。然后,我将设置对服务的调用,该服务将在我的视图模型的构造函数中使用,如上所示。一切现在都像魅力一样。我希望这对某人有用,因为我认为ClientChannelWrapper的想法非常适合Silverlight <-> WCF通信。请随时对此解决方案发表评论!